diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml
index 9b167ee66..4ff5e26cb 100644
--- a/.github/workflows/build-docs.yml
+++ b/.github/workflows/build-docs.yml
@@ -45,7 +45,7 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: "3.11"
- - uses: actions/cache@v3
+ - uses: actions/cache@v4
id: cache
with:
path: ${{ env.pythonLocation }}
@@ -86,7 +86,7 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: "3.11"
- - uses: actions/cache@v3
+ - uses: actions/cache@v4
id: cache
with:
path: ${{ env.pythonLocation }}
@@ -102,7 +102,7 @@ jobs:
pip install git+https://${{ secrets.FASTAPI_MKDOCS_MATERIAL_INSIDERS }}@github.com/pawamoy-insiders/mkdocstrings-python.git
- name: Update Languages
run: python ./scripts/docs.py update-languages
- - uses: actions/cache@v3
+ - uses: actions/cache@v4
with:
key: mkdocs-cards-${{ matrix.lang }}-${{ github.ref }}
path: docs/${{ matrix.lang }}/.cache
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 899e49057..a5cbf6da4 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -21,12 +21,17 @@ jobs:
# Issue ref: https://github.com/actions/setup-python/issues/436
# cache: "pip"
# cache-dependency-path: pyproject.toml
+ - uses: actions/cache@v4
+ id: cache
+ with:
+ path: ${{ env.pythonLocation }}
+ key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-publish
- name: Install build dependencies
run: pip install build
- name: Build distribution
run: python -m build
- name: Publish
- uses: pypa/gh-action-pypi-publish@v1.8.11
+ uses: pypa/gh-action-pypi-publish@v1.8.14
with:
password: ${{ secrets.PYPI_API_TOKEN }}
- name: Dump GitHub context
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index b6b173685..125265e53 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -8,6 +8,9 @@ on:
types:
- opened
- synchronize
+ schedule:
+ # cron every week on monday
+ - cron: "0 0 * * 1"
jobs:
lint:
@@ -25,7 +28,7 @@ jobs:
# Issue ref: https://github.com/actions/setup-python/issues/436
# cache: "pip"
# cache-dependency-path: pyproject.toml
- - uses: actions/cache@v3
+ - uses: actions/cache@v4
id: cache
with:
path: ${{ env.pythonLocation }}
@@ -63,7 +66,7 @@ jobs:
# Issue ref: https://github.com/actions/setup-python/issues/436
# cache: "pip"
# cache-dependency-path: pyproject.toml
- - uses: actions/cache@v3
+ - uses: actions/cache@v4
id: cache
with:
path: ${{ env.pythonLocation }}
diff --git a/docs/bn/docs/python-types.md b/docs/bn/docs/python-types.md
new file mode 100644
index 000000000..6923363dd
--- /dev/null
+++ b/docs/bn/docs/python-types.md
@@ -0,0 +1,537 @@
+# পাইথন এর টাইপ্স পরিচিতি
+
+Python-এ ঐচ্ছিক "টাইপ হিন্ট" (যা "টাইপ অ্যানোটেশন" নামেও পরিচিত) এর জন্য সাপোর্ট রয়েছে।
+
+এই **"টাইপ হিন্ট"** বা অ্যানোটেশনগুলি এক ধরণের বিশেষ সিনট্যাক্স যা একটি ভেরিয়েবলের টাইপ ঘোষণা করতে দেয়।
+
+ভেরিয়েবলগুলির জন্য টাইপ ঘোষণা করলে, এডিটর এবং টুলগুলি আপনাকে আরও ভালো সাপোর্ট দিতে পারে।
+
+এটি পাইথন টাইপ হিন্ট সম্পর্কে একটি দ্রুত **টিউটোরিয়াল / রিফ্রেশার** মাত্র। এটি **FastAPI** এর সাথে ব্যবহার করার জন্য শুধুমাত্র ন্যূনতম প্রয়োজনীয়তা কভার করে... যা আসলে খুব একটা বেশি না।
+
+**FastAPI** এই টাইপ হিন্টগুলির উপর ভিত্তি করে নির্মিত, যা এটিকে অনেক সুবিধা এবং লাভ প্রদান করে।
+
+তবে, আপনি যদি কখনো **FastAPI** ব্যবহার নাও করেন, তবুও এগুলি সম্পর্কে একটু শেখা আপনার উপকারে আসবে।
+
+!!! Note
+ যদি আপনি একজন Python বিশেষজ্ঞ হন, এবং টাইপ হিন্ট সম্পর্কে সবকিছু জানেন, তাহলে পরবর্তী অধ্যায়ে চলে যান।
+
+## প্রেরণা
+
+চলুন একটি সাধারণ উদাহরণ দিয়ে শুরু করি:
+
+```Python
+{!../../../docs_src/python_types/tutorial001.py!}
+```
+
+এই প্রোগ্রামটি কল করলে আউটপুট হয়:
+
+```
+John Doe
+```
+
+ফাংশনটি নিম্নলিখিত কাজ করে:
+
+* `first_name` এবং `last_name` নেয়।
+* প্রতিটির প্রথম অক্ষরকে `title()` ব্যবহার করে বড় হাতের অক্ষরে রূপান্তর করে।
+* তাদেরকে মাঝখানে একটি স্পেস দিয়ে concatenate করে।
+
+```Python hl_lines="2"
+{!../../../docs_src/python_types/tutorial001.py!}
+```
+
+### এটি সম্পাদনা করুন
+
+এটি একটি খুব সাধারণ প্রোগ্রাম।
+
+কিন্তু এখন কল্পনা করুন যে আপনি এটি শুরু থেকে লিখছিলেন।
+
+এক পর্যায়ে আপনি ফাংশনের সংজ্ঞা শুরু করেছিলেন, আপনার প্যারামিটারগুলি প্রস্তুত ছিল...
+
+কিন্তু তারপর আপনাকে "সেই method কল করতে হবে যা প্রথম অক্ষরকে বড় হাতের অক্ষরে রূপান্তর করে"।
+
+এটা কি `upper` ছিল? নাকি `uppercase`? `first_uppercase`? `capitalize`?
+
+তারপর, আপনি পুরোনো প্রোগ্রামারের বন্ধু, এডিটর অটোকমপ্লিশনের সাহায্যে নেওয়ার চেষ্টা করেন।
+
+আপনি ফাংশনের প্রথম প্যারামিটার `first_name` টাইপ করেন, তারপর একটি ডট (`.`) টাইপ করেন এবং `Ctrl+Space` চাপেন অটোকমপ্লিশন ট্রিগার করার জন্য।
+
+কিন্তু, দুর্ভাগ্যবশত, আপনি কিছুই উপযোগী পান না:
+
+
+
+### টাইপ যোগ করুন
+
+আসুন আগের সংস্করণ থেকে একটি লাইন পরিবর্তন করি।
+
+আমরা ঠিক এই অংশটি পরিবর্তন করব অর্থাৎ ফাংশনের প্যারামিটারগুলি, এইগুলি:
+
+```Python
+ first_name, last_name
+```
+
+থেকে এইগুলি:
+
+```Python
+ first_name: str, last_name: str
+```
+
+ব্যাস।
+
+এগুলিই "টাইপ হিন্ট":
+
+```Python hl_lines="1"
+{!../../../docs_src/python_types/tutorial002.py!}
+```
+
+এটি ডিফল্ট ভ্যালু ঘোষণা করার মত নয় যেমন:
+
+```Python
+ first_name="john", last_name="doe"
+```
+
+এটি একটি ভিন্ন জিনিস।
+
+আমরা সমান (`=`) নয়, কোলন (`:`) ব্যবহার করছি।
+
+এবং টাইপ হিন্ট যোগ করা সাধারণত তেমন কিছু পরিবর্তন করে না যা টাইপ হিন্ট ছাড়াই ঘটত।
+
+কিন্তু এখন, কল্পনা করুন আপনি আবার সেই ফাংশন তৈরির মাঝখানে আছেন, কিন্তু টাইপ হিন্ট সহ।
+
+একই পর্যায়ে, আপনি অটোকমপ্লিট ট্রিগার করতে `Ctrl+Space` চাপেন এবং আপনি দেখতে পান:
+
+
+
+এর সাথে, আপনি অপশনগুলি দেখে, স্ক্রল করতে পারেন, যতক্ষণ না আপনি এমন একটি অপশন খুঁজে পান যা কিছু মনে পরিয়ে দেয়:
+
+
+
+## আরও প্রেরণা
+
+এই ফাংশনটি দেখুন, এটিতে ইতিমধ্যে টাইপ হিন্ট রয়েছে:
+
+```Python hl_lines="1"
+{!../../../docs_src/python_types/tutorial003.py!}
+```
+
+এডিটর ভেরিয়েবলগুলির টাইপ জানার কারণে, আপনি শুধুমাত্র অটোকমপ্লিশনই পান না, আপনি এরর চেকও পান:
+
+
+
+এখন আপনি জানেন যে আপনাকে এটি ঠিক করতে হবে, `age`-কে একটি স্ট্রিং হিসেবে রূপান্তর করতে `str(age)` ব্যবহার করতে হবে:
+
+```Python hl_lines="2"
+{!../../../docs_src/python_types/tutorial004.py!}
+```
+
+## টাইপ ঘোষণা
+
+আপনি এতক্ষন টাইপ হিন্ট ঘোষণা করার মূল স্থানটি দেখে ফেলেছেন-- ফাংশন প্যারামিটার হিসেবে।
+
+সাধারণত এটি **FastAPI** এর ক্ষেত্রেও একই।
+
+### সিম্পল টাইপ
+
+আপনি `str` ছাড়াও সমস্ত স্ট্যান্ডার্ড পাইথন টাইপ ঘোষণা করতে পারেন।
+
+উদাহরণস্বরূপ, আপনি এগুলো ব্যবহার করতে পারেন:
+
+* `int`
+* `float`
+* `bool`
+* `bytes`
+
+```Python hl_lines="1"
+{!../../../docs_src/python_types/tutorial005.py!}
+```
+
+### টাইপ প্যারামিটার সহ জেনেরিক টাইপ
+
+কিছু ডাটা স্ট্রাকচার অন্যান্য মান ধারণ করতে পারে, যেমন `dict`, `list`, `set` এবং `tuple`। এবং অভ্যন্তরীণ মানগুলোরও নিজেদের টাইপ থাকতে পারে।
+
+এই ধরনের টাইপগুলিকে বলা হয় "**জেনেরিক**" টাইপ এবং এগুলিকে তাদের অভ্যন্তরীণ টাইপগুলি সহ ঘোষণা করা সম্ভব।
+
+এই টাইপগুলি এবং অভ্যন্তরীণ টাইপগুলি ঘোষণা করতে, আপনি Python মডিউল `typing` ব্যবহার করতে পারেন। এটি বিশেষভাবে এই টাইপ হিন্টগুলি সমর্থন করার জন্য রয়েছে।
+
+#### Python এর নতুন সংস্করণ
+
+`typing` ব্যবহার করা সিনট্যাক্সটি Python 3.6 থেকে সর্বশেষ সংস্করণগুলি পর্যন্ত, অর্থাৎ Python 3.9, Python 3.10 ইত্যাদি সহ সকল সংস্করণের সাথে **সামঞ্জস্যপূর্ণ**।
+
+Python যত এগিয়ে যাচ্ছে, **নতুন সংস্করণগুলি** এই টাইপ অ্যানোটেশনগুলির জন্য তত উন্নত সাপোর্ট নিয়ে আসছে এবং অনেক ক্ষেত্রে আপনাকে টাইপ অ্যানোটেশন ঘোষণা করতে `typing` মডিউল ইম্পোর্ট এবং ব্যবহার করার প্রয়োজন হবে না।
+
+যদি আপনি আপনার প্রজেক্টের জন্য Python-এর আরও সাম্প্রতিক সংস্করণ নির্বাচন করতে পারেন, তাহলে আপনি সেই অতিরিক্ত সরলতা থেকে সুবিধা নিতে পারবেন।
+
+ডক্সে রয়েছে Python-এর প্রতিটি সংস্করণের সাথে সামঞ্জস্যপূর্ণ উদাহরণগুলি (যখন পার্থক্য আছে)।
+
+উদাহরণস্বরূপ, "**Python 3.6+**" মানে এটি Python 3.6 বা তার উপরে সামঞ্জস্যপূর্ণ (যার মধ্যে 3.7, 3.8, 3.9, 3.10, ইত্যাদি অন্তর্ভুক্ত)। এবং "**Python 3.9+**" মানে এটি Python 3.9 বা তার উপরে সামঞ্জস্যপূর্ণ (যার মধ্যে 3.10, ইত্যাদি অন্তর্ভুক্ত)।
+
+যদি আপনি Python-এর **সর্বশেষ সংস্করণগুলি ব্যবহার করতে পারেন**, তাহলে সর্বশেষ সংস্করণের জন্য উদাহরণগুলি ব্যবহার করুন, সেগুলি আপনাকে **সর্বোত্তম এবং সহজতম সিনট্যাক্স** প্রদান করবে, যেমন, "**Python 3.10+**"।
+
+#### লিস্ট
+
+উদাহরণস্বরূপ, একটি ভেরিয়েবলকে `str`-এর একটি `list` হিসেবে সংজ্ঞায়িত করা যাক।
+
+=== "Python 3.9+"
+
+ ভেরিয়েবলটি ঘোষণা করুন, একই কোলন (`:`) সিনট্যাক্স ব্যবহার করে।
+
+ টাইপ হিসেবে, `list` ব্যবহার করুন।
+
+ যেহেতু লিস্ট এমন একটি টাইপ যা অভ্যন্তরীণ টাইপগুলি ধারণ করে, আপনি তাদের স্কোয়ার ব্রাকেটের ভিতরে ব্যবহার করুন:
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/python_types/tutorial006_py39.py!}
+ ```
+
+=== "Python 3.8+"
+
+ `typing` থেকে `List` (বড় হাতের `L` দিয়ে) ইমপোর্ট করুন:
+
+ ``` Python hl_lines="1"
+ {!> ../../../docs_src/python_types/tutorial006.py!}
+ ```
+
+ ভেরিয়েবলটি ঘোষণা করুন, একই কোলন (`:`) সিনট্যাক্স ব্যবহার করে।
+
+ টাইপ হিসেবে, `typing` থেকে আপনার ইম্পোর্ট করা `List` ব্যবহার করুন।
+
+ যেহেতু লিস্ট এমন একটি টাইপ যা অভ্যন্তরীণ টাইপগুলি ধারণ করে, আপনি তাদের স্কোয়ার ব্রাকেটের ভিতরে করুন:
+
+ ```Python hl_lines="4"
+ {!> ../../../docs_src/python_types/tutorial006.py!}
+ ```
+
+!!! Info
+ স্কোয়ার ব্রাকেট এর ভিতরে ব্যবহৃত এইসব অভন্তরীন টাইপগুলোকে "ইন্টারনাল টাইপ" বলে।
+
+ এই উদাহরণে, এটি হচ্ছে `List`(অথবা পাইথন ৩.৯ বা তার উপরের সংস্করণের ক্ষেত্রে `list`) এ পাস করা টাইপ প্যারামিটার।
+
+এর অর্থ হচ্ছে: "ভেরিয়েবল `items` একটি `list`, এবং এই লিস্টের প্রতিটি আইটেম একটি `str`।"
+
+!!! Tip
+ যদি আপনি Python 3.9 বা তার উপরে ব্যবহার করেন, আপনার `typing` থেকে `List` আমদানি করতে হবে না, আপনি সাধারণ `list` ওই টাইপের পরিবর্তে ব্যবহার করতে পারেন।
+
+এর মাধ্যমে, আপনার এডিটর লিস্ট থেকে আইটেম প্রসেস করার সময় সাপোর্ট প্রদান করতে পারবে:
+
+
+
+টাইপগুলি ছাড়া, এটি করা প্রায় অসম্ভব।
+
+লক্ষ্য করুন যে ভেরিয়েবল `item` হল `items` লিস্টের একটি এলিমেন্ট।
+
+তবুও, এডিটর জানে যে এটি একটি `str`, এবং তার জন্য সাপোর্ট প্রদান করে।
+
+#### টাপল এবং সেট
+
+আপনি `tuple` এবং `set` ঘোষণা করার জন্য একই প্রক্রিয়া অনুসরণ করবেন:
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/python_types/tutorial007_py39.py!}
+ ```
+
+=== "Python 3.8+"
+
+ ```Python hl_lines="1 4"
+ {!> ../../../docs_src/python_types/tutorial007.py!}
+ ```
+
+এর মানে হল:
+
+* ভেরিয়েবল `items_t` হল একটি `tuple` যা ৩টি আইটেম ধারণ করে, একটি `int`, অন্য একটি `int`, এবং একটি `str`।
+* ভেরিয়েবল `items_s` হল একটি `set`, এবং এর প্রতিটি আইটেম হল `bytes` টাইপের।
+
+#### ডিক্ট
+
+একটি `dict` সংজ্ঞায়িত করতে, আপনি ২টি টাইপ প্যারামিটার কমা দ্বারা পৃথক করে দেবেন।
+
+প্রথম টাইপ প্যারামিটারটি হল `dict`-এর কীগুলির জন্য।
+
+দ্বিতীয় টাইপ প্যারামিটারটি হল `dict`-এর মানগুলির জন্য:
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/python_types/tutorial008_py39.py!}
+ ```
+
+=== "Python 3.8+"
+
+ ```Python hl_lines="1 4"
+ {!> ../../../docs_src/python_types/tutorial008.py!}
+ ```
+
+
+এর মানে হল:
+
+* ভেরিয়েবল `prices` হল একটি `dict`:
+ * এই `dict`-এর কীগুলি হল `str` টাইপের (ধরা যাক, প্রতিটি আইটেমের নাম)।
+ * এই `dict`-এর মানগুলি হল `float` টাইপের (ধরা যাক, প্রতিটি আইটেমের দাম)।
+
+#### ইউনিয়ন
+
+আপনি একটি ভেরিয়েবলকে এমনভাবে ঘোষণা করতে পারেন যেন তা **একাধিক টাইপের** হয়, উদাহরণস্বরূপ, একটি `int` অথবা `str`।
+
+Python 3.6 এবং তার উপরের সংস্করণগুলিতে (Python 3.10 অন্তর্ভুক্ত) আপনি `typing` থেকে `Union` টাইপ ব্যবহার করতে পারেন এবং স্কোয়ার ব্র্যাকেটের মধ্যে গ্রহণযোগ্য টাইপগুলি রাখতে পারেন।
+
+Python 3.10-এ একটি **নতুন সিনট্যাক্স** আছে যেখানে আপনি সম্ভাব্য টাইপগুলিকে একটি ভার্টিকাল বার (`|`) দ্বারা পৃথক করতে পারেন।
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/python_types/tutorial008b_py310.py!}
+ ```
+
+=== "Python 3.8+"
+
+ ```Python hl_lines="1 4"
+ {!> ../../../docs_src/python_types/tutorial008b.py!}
+ ```
+
+উভয় ক্ষেত্রেই এর মানে হল যে `item` হতে পারে একটি `int` অথবা `str`।
+
+#### সম্ভবত `None`
+
+আপনি এমনভাবে ঘোষণা করতে পারেন যে একটি মান হতে পারে এক টাইপের, যেমন `str`, আবার এটি `None`-ও হতে পারে।
+
+Python 3.6 এবং তার উপরের সংস্করণগুলিতে (Python 3.10 অনতর্ভুক্ত) আপনি `typing` মডিউল থেকে `Optional` ইমপোর্ট করে এটি ঘোষণা এবং ব্যবহার করতে পারেন।
+
+```Python hl_lines="1 4"
+{!../../../docs_src/python_types/tutorial009.py!}
+```
+
+`Optional[str]` ব্যবহার করা মানে হল শুধু `str` নয়, এটি হতে পারে `None`-ও, যা আপনার এডিটরকে সেই ত্রুটিগুলি শনাক্ত করতে সাহায্য করবে যেখানে আপনি ধরে নিচ্ছেন যে একটি মান সবসময় `str` হবে, অথচ এটি `None`-ও হতে পারেও।
+
+`Optional[Something]` মূলত `Union[Something, None]`-এর একটি শর্টকাট, এবং তারা সমতুল্য।
+
+এর মানে হল, Python 3.10-এ, আপনি টাইপগুলির ইউনিয়ন ঘোষণা করতে `Something | None` ব্যবহার করতে পারেন:
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/python_types/tutorial009_py310.py!}
+ ```
+
+=== "Python 3.8+"
+
+ ```Python hl_lines="1 4"
+ {!> ../../../docs_src/python_types/tutorial009.py!}
+ ```
+
+=== "Python 3.8+ বিকল্প"
+
+ ```Python hl_lines="1 4"
+ {!> ../../../docs_src/python_types/tutorial009b.py!}
+ ```
+
+#### `Union` বা `Optional` ব্যবহার
+
+যদি আপনি Python 3.10-এর নীচের সংস্করণ ব্যবহার করেন, তবে এখানে আমার খুবই **ব্যক্তিগত** দৃষ্টিভঙ্গি থেকে একটি টিপস:
+
+* 🚨 `Optional[SomeType]` ব্যবহার এড়িয়ে চলুন।
+* এর পরিবর্তে ✨ **`Union[SomeType, None]` ব্যবহার করুন** ✨।
+
+উভয়ই সমতুল্য এবং মূলে একই, কিন্তু আমি `Union`-এর পক্ষে সুপারিশ করব কারণ "**অপশনাল**" শব্দটি মনে হতে পারে যে মানটি ঐচ্ছিক,অথচ এটি আসলে মানে "এটি হতে পারে `None`", এমনকি যদি এটি ঐচ্ছিক না হয়েও আবশ্যিক হয়।
+
+আমি মনে করি `Union[SomeType, None]` এর অর্থ আরও স্পষ্টভাবে প্রকাশ করে।
+
+এটি কেবল শব্দ এবং নামের ব্যাপার। কিন্তু সেই শব্দগুলি আপনি এবং আপনার সহকর্মীরা কোড সম্পর্কে কীভাবে চিন্তা করেন তা প্রভাবিত করতে পারে।
+
+একটি উদাহরণ হিসেবে, এই ফাংশনটি নিন:
+
+```Python hl_lines="1 4"
+{!../../../docs_src/python_types/tutorial009c.py!}
+```
+
+`name` প্যারামিটারটি `Optional[str]` হিসেবে সংজ্ঞায়িত হয়েছে, কিন্তু এটি **অপশনাল নয়**, আপনি প্যারামিটার ছাড়া ফাংশনটি কল করতে পারবেন না:
+
+```Python
+say_hi() # ওহ না, এটি একটি ত্রুটি নিক্ষেপ করবে! 😱
+```
+
+`name` প্যারামিটারটি **এখনও আবশ্যিক** (নন-অপশনাল) কারণ এটির কোনো ডিফল্ট মান নেই। তবুও, `name` এর মান হিসেবে `None` গ্রহণযোগ্য:
+
+```Python
+say_hi(name=None) # এটি কাজ করে, None বৈধ 🎉
+```
+
+সুখবর হল, একবার আপনি Python 3.10 ব্যবহার করা শুরু করলে, আপনাকে এগুলোর ব্যাপারে আর চিন্তা করতে হবে না, যেহুতু আপনি | ব্যবহার করেই ইউনিয়ন ঘোষণা করতে পারবেন:
+
+```Python hl_lines="1 4"
+{!../../../docs_src/python_types/tutorial009c_py310.py!}
+```
+
+এবং তারপর আপনাকে নামগুলি যেমন `Optional` এবং `Union` নিয়ে আর চিন্তা করতে হবে না। 😎
+
+#### জেনেরিক টাইপস
+
+স্কোয়ার ব্র্যাকেটে টাইপ প্যারামিটার নেওয়া এই টাইপগুলিকে **জেনেরিক টাইপ** বা **জেনেরিকস** বলা হয়, যেমন:
+
+=== "Python 3.10+"
+ আপনি সেই একই বিল্টইন টাইপ জেনেরিক্স হিসেবে ব্যবহার করতে পারবেন(ভিতরে টাইপ সহ স্কয়ারে ব্রাকেট দিয়ে):
+
+ * `list`
+ * `tuple`
+ * `set`
+ * `dict`
+
+ এবং Python 3.8 এর মতোই, `typing` মডিউল থেকে:
+
+ * `Union`
+ * `Optional` (Python 3.8 এর মতোই)
+ * ...এবং অন্যান্য।
+
+ Python 3.10-এ, `Union` এবং `Optional` জেনেরিকস ব্যবহার করার বিকল্প হিসেবে, আপনি টাইপগুলির ইউনিয়ন ঘোষণা করতে ভার্টিকাল বার (`|`) ব্যবহার করতে পারেন, যা ওদের থেকে অনেক ভালো এবং সহজ।
+
+=== "Python 3.9+"
+
+ আপনি সেই একই বিল্টইন টাইপ জেনেরিক্স হিসেবে ব্যবহার করতে পারবেন(ভিতরে টাইপ সহ স্কয়ারে ব্রাকেট দিয়ে):
+
+ * `list`
+ * `tuple`
+ * `set`
+ * `dict`
+
+ এবং Python 3.8 এর মতোই, `typing` মডিউল থেকে:
+
+ * `Union`
+ * `Optional`
+ * ...এবং অন্যান্য।
+
+=== "Python 3.8+"
+
+ * `List`
+ * `Tuple`
+ * `Set`
+ * `Dict`
+ * `Union`
+ * `Optional`
+ * ...এবং অন্যান্য।
+
+### ক্লাস হিসেবে টাইপস
+
+আপনি একটি ভেরিয়েবলের টাইপ হিসেবে একটি ক্লাস ঘোষণা করতে পারেন।
+
+ধরুন আপনার কাছে `Person` নামে একটি ক্লাস আছে, যার একটি নাম আছে:
+
+```Python hl_lines="1-3"
+{!../../../docs_src/python_types/tutorial010.py!}
+```
+
+তারপর আপনি একটি ভেরিয়েবলকে `Person` টাইপের হিসেবে ঘোষণা করতে পারেন:
+
+```Python hl_lines="6"
+{!../../../docs_src/python_types/tutorial010.py!}
+```
+
+এবং তারপর, আবার, আপনি এডিটর সাপোর্ট পেয়ে যাবেন:
+
+
+
+লক্ষ্য করুন যে এর মানে হল "`one_person` হল ক্লাস `Person`-এর একটি **ইন্সট্যান্স**।"
+
+এর মানে এটি নয় যে "`one_person` হল **ক্লাস** যাকে বলা হয় `Person`।"
+
+## Pydantic মডেল
+
+[Pydantic](https://docs.pydantic.dev/) হল একটি Python লাইব্রেরি যা ডাটা ভ্যালিডেশন সম্পাদন করে।
+
+আপনি ডাটার "আকার" এট্রিবিউট সহ ক্লাস হিসেবে ঘোষণা করেন।
+
+এবং প্রতিটি এট্রিবিউট এর একটি টাইপ থাকে।
+
+তারপর আপনি যদি কিছু মান দিয়ে সেই ক্লাসের একটি ইন্সট্যান্স তৈরি করেন-- এটি মানগুলিকে ভ্যালিডেট করবে, প্রয়োজন অনুযায়ী তাদেরকে উপযুক্ত টাইপে রূপান্তর করবে এবং আপনাকে সমস্ত ডাটা সহ একটি অবজেক্ট প্রদান করবে।
+
+এবং আপনি সেই ফলাফল অবজেক্টের সাথে এডিটর সাপোর্ট পাবেন।
+
+অফিসিয়াল Pydantic ডক্স থেকে একটি উদাহরণ:
+
+=== "Python 3.10+"
+
+ ```Python
+ {!> ../../../docs_src/python_types/tutorial011_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python
+ {!> ../../../docs_src/python_types/tutorial011_py39.py!}
+ ```
+
+=== "Python 3.8+"
+
+ ```Python
+ {!> ../../../docs_src/python_types/tutorial011.py!}
+ ```
+
+!!! Info
+ [Pydantic সম্পর্কে আরও জানতে, এর ডকুমেন্টেশন দেখুন](https://docs.pydantic.dev/)।
+
+**FastAPI** মূলত Pydantic-এর উপর নির্মিত।
+
+আপনি এই সমস্ত কিছুর অনেক বাস্তবসম্মত উদাহরণ পাবেন [টিউটোরিয়াল - ইউজার গাইডে](https://fastapi.tiangolo.com/tutorial/)।
+
+!!! Tip
+ যখন আপনি `Optional` বা `Union[Something, None]` ব্যবহার করেন এবং কোনো ডিফল্ট মান না থাকে, Pydantic-এর একটি বিশেষ আচরণ রয়েছে, আপনি Pydantic ডকুমেন্টেশনে [Required Optional fields](https://docs.pydantic.dev/latest/concepts/models/#required-optional-fields) সম্পর্কে আরও পড়তে পারেন।
+
+## মেটাডাটা অ্যানোটেশন সহ টাইপ হিন্টস
+
+Python-এ এমন একটি ফিচার আছে যা `Annotated` ব্যবহার করে এই টাইপ হিন্টগুলিতে **অতিরিক্ত মেটাডাটা** রাখতে দেয়।
+
+=== "Python 3.9+"
+
+ Python 3.9-এ, `Annotated` স্ট্যান্ডার্ড লাইব্রেরিতে অন্তর্ভুক্ত, তাই আপনি এটি `typing` থেকে ইমপোর্ট করতে পারেন।
+
+ ```Python hl_lines="1 4"
+ {!> ../../../docs_src/python_types/tutorial013_py39.py!}
+ ```
+
+=== "Python 3.8+"
+
+ Python 3.9-এর নীচের সংস্করণগুলিতে, আপনি `Annotated`-কে `typing_extensions` থেকে ইমপোর্ট করেন।
+
+ এটি **FastAPI** এর সাথে ইতিমদ্ধে ইনস্টল হয়ে থাকবে।
+
+ ```Python hl_lines="1 4"
+ {!> ../../../docs_src/python_types/tutorial013.py!}
+ ```
+
+Python নিজে এই `Annotated` দিয়ে কিছুই করে না। এবং এডিটর এবং অন্যান্য টুলগুলির জন্য, টাইপটি এখনও `str`।
+
+কিন্তু আপনি এই `Annotated` এর মধ্যকার জায়গাটির মধ্যে **FastAPI**-এ কীভাবে আপনার অ্যাপ্লিকেশন আচরণ করুক তা সম্পর্কে অতিরিক্ত মেটাডাটা প্রদান করার জন্য ব্যবহার করতে পারেন।
+
+মনে রাখার গুরুত্বপূর্ণ বিষয় হল যে **প্রথম *টাইপ প্যারামিটার*** আপনি `Annotated`-এ পাস করেন সেটি হল **আসল টাইপ**। বাকি শুধুমাত্র অন্যান্য টুলগুলির জন্য মেটাডাটা।
+
+এখন আপনার কেবল জানা প্রয়োজন যে `Annotated` বিদ্যমান, এবং এটি স্ট্যান্ডার্ড Python। 😎
+
+পরবর্তীতে আপনি দেখবেন এটি কতটা **শক্তিশালী** হতে পারে।
+
+!!! Tip
+ এটি **স্ট্যান্ডার্ড Python** হওয়ার মানে হল আপনি আপনার এডিটরে, আপনি যে টুলগুলি কোড বিশ্লেষণ এবং রিফ্যাক্টর করার জন্য ব্যবহার করেন তাতে **সেরা সম্ভাব্য ডেভেলপার এক্সপেরিয়েন্স** পাবেন। ✨
+
+ এবং এছাড়াও আপনার কোড অন্যান্য অনেক Python টুল এবং লাইব্রেরিগুলির সাথে খুব সামঞ্জস্যপূর্ণ হবে। 🚀
+
+## **FastAPI**-এ টাইপ হিন্টস
+
+**FastAPI** এই টাইপ হিন্টগুলি ব্যবহার করে বেশ কিছু জিনিস করে।
+
+**FastAPI**-এ আপনি টাইপ হিন্টগুলি সহ প্যারামিটার ঘোষণা করেন এবং আপনি পান:
+
+* **এডিটর সাপোর্ট**।
+* **টাইপচেক**।
+
+...এবং **FastAPI** একই ঘোষণাগুলি ব্যবহার করে:
+
+* **রিকুইরেমেন্টস সংজ্ঞায়িত করে**: রিকোয়েস্ট পাথ প্যারামিটার, কুয়েরি প্যারামিটার, হেডার, বডি, ডিপেন্ডেন্সিস, ইত্যাদি থেকে।
+* **ডেটা রূপান্তর করে**: রিকোয়েস্ট থেকে প্রয়োজনীয় টাইপে ডেটা।
+* **ডেটা যাচাই করে**: প্রতিটি রিকোয়েস্ট থেকে আসা ডেটা:
+ * যখন ডেটা অবৈধ হয় তখন **স্বয়ংক্রিয় ত্রুটি** গ্রাহকের কাছে ফেরত পাঠানো।
+* **API ডকুমেন্টেশন তৈরি করে**: OpenAPI ব্যবহার করে:
+ * যা স্বয়ংক্রিয় ইন্টার্যাক্টিভ ডকুমেন্টেশন ইউজার ইন্টারফেস দ্বারা ব্যবহৃত হয়।
+
+এই সব কিছু আপনার কাছে অস্পষ্ট মনে হতে পারে। চিন্তা করবেন না। আপনি [টিউটোরিয়াল - ইউজার গাইড](https://fastapi.tiangolo.com/tutorial/) এ এই সব কিছু প্র্যাকটিসে দেখতে পাবেন।
+
+গুরুত্বপূর্ণ বিষয় হল, আপনি যদি স্ট্যান্ডার্ড Python টাইপগুলি ব্যবহার করেন, তবে আরও বেশি ক্লাস, ডেকোরেটর ইত্যাদি যোগ না করেই একই স্থানে **FastAPI** আপনার অনেক কাজ করে দিবে।
+
+!!! Info
+ যদি আপনি টিউটোরিয়ালের সমস্ত বিষয় পড়ে ফেলে থাকেন এবং টাইপ সম্পর্কে আরও জানতে চান, তবে একটি ভালো রিসোর্স হল [mypy এর "cheat sheet"](https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html)। এই "cheat sheet" এ আপনি Python টাইপ হিন্ট সম্পর্কে বেসিক থেকে উন্নত লেভেলের ধারণা পেতে পারেন, যা আপনার কোডে টাইপ সেফটি এবং স্পষ্টতা বাড়াতে সাহায্য করবে।
diff --git a/docs/de/docs/advanced/generate-clients.md b/docs/de/docs/advanced/generate-clients.md
index 2fcba5956..7d1d69353 100644
--- a/docs/de/docs/advanced/generate-clients.md
+++ b/docs/de/docs/advanced/generate-clients.md
@@ -10,7 +10,7 @@ Es gibt viele Tools zum Generieren von Clients aus **OpenAPI**.
Ein gängiges Tool ist OpenAPI Generator.
-Wenn Sie ein **Frontend** erstellen, ist openapi-typescript-codegen eine sehr interessante Alternative.
+Wenn Sie ein **Frontend** erstellen, ist openapi-ts eine sehr interessante Alternative.
## Client- und SDK-Generatoren – Sponsor
@@ -58,14 +58,14 @@ Und dieselben Informationen aus den Modellen, die in OpenAPI enthalten sind, kö
Nachdem wir nun die Anwendung mit den Modellen haben, können wir den Client-Code für das Frontend generieren.
-#### `openapi-typescript-codegen` installieren
+#### `openapi-ts` installieren
-Sie können `openapi-typescript-codegen` in Ihrem Frontend-Code installieren mit:
+Sie können `openapi-ts` in Ihrem Frontend-Code installieren mit:
```console
-$ npm install openapi-typescript-codegen --save-dev
+$ npm install @hey-api/openapi-ts --save-dev
---> 100%
```
@@ -74,7 +74,7 @@ $ npm install openapi-typescript-codegen --save-dev
#### Client-Code generieren
-Um den Client-Code zu generieren, können Sie das Kommandozeilentool `openapi` verwenden, das soeben installiert wurde.
+Um den Client-Code zu generieren, können Sie das Kommandozeilentool `openapi-ts` verwenden, das soeben installiert wurde.
Da es im lokalen Projekt installiert ist, könnten Sie diesen Befehl wahrscheinlich nicht direkt aufrufen, sondern würden ihn in Ihre Datei `package.json` einfügen.
@@ -87,12 +87,12 @@ Diese könnte so aussehen:
"description": "",
"main": "index.js",
"scripts": {
- "generate-client": "openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios --useOptions --useUnionTypes"
+ "generate-client": "openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios"
},
"author": "",
"license": "",
"devDependencies": {
- "openapi-typescript-codegen": "^0.20.1",
+ "@hey-api/openapi-ts": "^0.27.38",
"typescript": "^4.6.2"
}
}
@@ -106,7 +106,7 @@ Nachdem Sie das NPM-Skript `generate-client` dort stehen haben, können Sie es a
$ npm run generate-client
frontend-app@1.0.0 generate-client /home/user/code/frontend-app
-> openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios --useOptions --useUnionTypes
+> openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios
```
@@ -254,12 +254,12 @@ Da das Endergebnis nun in einer Datei `openapi.json` vorliegt, würden Sie die `
"description": "",
"main": "index.js",
"scripts": {
- "generate-client": "openapi --input ./openapi.json --output ./src/client --client axios --useOptions --useUnionTypes"
+ "generate-client": "openapi-ts --input ./openapi.json --output ./src/client --client axios"
},
"author": "",
"license": "",
"devDependencies": {
- "openapi-typescript-codegen": "^0.20.1",
+ "@hey-api/openapi-ts": "^0.27.38",
"typescript": "^4.6.2"
}
}
diff --git a/docs/de/docs/tutorial/response-status-code.md b/docs/de/docs/tutorial/response-status-code.md
new file mode 100644
index 000000000..a9cc238f8
--- /dev/null
+++ b/docs/de/docs/tutorial/response-status-code.md
@@ -0,0 +1,89 @@
+# Response-Statuscode
+
+So wie ein Responsemodell, können Sie auch einen HTTP-Statuscode für die Response deklarieren, mithilfe des Parameters `status_code`, und zwar in jeder der *Pfadoperationen*:
+
+* `@app.get()`
+* `@app.post()`
+* `@app.put()`
+* `@app.delete()`
+* usw.
+
+```Python hl_lines="6"
+{!../../../docs_src/response_status_code/tutorial001.py!}
+```
+
+!!! note "Hinweis"
+ Beachten Sie, dass `status_code` ein Parameter der „Dekorator“-Methode ist (`get`, `post`, usw.). Nicht der *Pfadoperation-Funktion*, so wie die anderen Parameter und der Body.
+
+Dem `status_code`-Parameter wird eine Zahl mit dem HTTP-Statuscode übergeben.
+
+!!! info
+ Alternativ kann `status_code` auch ein `IntEnum` erhalten, so wie Pythons
```console
-$ npm install openapi-typescript-codegen --save-dev
+$ npm install @hey-api/openapi-ts --save-dev
---> 100%
```
@@ -62,7 +62,7 @@ $ npm install openapi-typescript-codegen --save-dev
#### 🏗 👩💻 📟
-🏗 👩💻 📟 👆 💪 ⚙️ 📋 ⏸ 🈸 `openapi` 👈 🔜 🔜 ❎.
+🏗 👩💻 📟 👆 💪 ⚙️ 📋 ⏸ 🈸 `openapi-ts` 👈 🔜 🔜 ❎.
↩️ ⚫️ ❎ 🇧🇿 🏗, 👆 🎲 🚫🔜 💪 🤙 👈 📋 🔗, ✋️ 👆 🔜 🚮 ⚫️ 🔛 👆 `package.json` 📁.
@@ -75,12 +75,12 @@ $ npm install openapi-typescript-codegen --save-dev
"description": "",
"main": "index.js",
"scripts": {
- "generate-client": "openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios"
+ "generate-client": "openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios"
},
"author": "",
"license": "",
"devDependencies": {
- "openapi-typescript-codegen": "^0.20.1",
+ "@hey-api/openapi-ts": "^0.27.38",
"typescript": "^4.6.2"
}
}
@@ -94,7 +94,7 @@ $ npm install openapi-typescript-codegen --save-dev
$ npm run generate-client
frontend-app@1.0.0 generate-client /home/user/code/frontend-app
-> openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios
+> openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios
```
@@ -235,12 +235,12 @@ FastAPI ⚙️ **😍 🆔** 🔠 *➡ 🛠️*, ⚫️ ⚙️ **🛠️ 🆔**
"description": "",
"main": "index.js",
"scripts": {
- "generate-client": "openapi --input ./openapi.json --output ./src/client --client axios"
+ "generate-client": "openapi-ts --input ./openapi.json --output ./src/client --client axios"
},
"author": "",
"license": "",
"devDependencies": {
- "openapi-typescript-codegen": "^0.20.1",
+ "@hey-api/openapi-ts": "^0.27.38",
"typescript": "^4.6.2"
}
}
diff --git a/docs/en/data/github_sponsors.yml b/docs/en/data/github_sponsors.yml
index fb690708f..385bcb498 100644
--- a/docs/en/data/github_sponsors.yml
+++ b/docs/en/data/github_sponsors.yml
@@ -2,9 +2,6 @@ sponsors:
- - login: bump-sh
avatarUrl: https://avatars.githubusercontent.com/u/33217836?v=4
url: https://github.com/bump-sh
- - login: Alek99
- avatarUrl: https://avatars.githubusercontent.com/u/38776361?u=bd6c163fe787c2de1a26c881598e54b67e2482dd&v=4
- url: https://github.com/Alek99
- login: porter-dev
avatarUrl: https://avatars.githubusercontent.com/u/62078005?v=4
url: https://github.com/porter-dev
@@ -14,6 +11,9 @@ sponsors:
- login: zanfaruqui
avatarUrl: https://avatars.githubusercontent.com/u/104461687?v=4
url: https://github.com/zanfaruqui
+ - login: Alek99
+ avatarUrl: https://avatars.githubusercontent.com/u/38776361?u=bd6c163fe787c2de1a26c881598e54b67e2482dd&v=4
+ url: https://github.com/Alek99
- login: cryptapi
avatarUrl: https://avatars.githubusercontent.com/u/44925437?u=61369138589bc7fee6c417f3fbd50fbd38286cc4&v=4
url: https://github.com/cryptapi
@@ -56,24 +56,21 @@ sponsors:
- login: acsone
avatarUrl: https://avatars.githubusercontent.com/u/7601056?v=4
url: https://github.com/acsone
-- - login: Trivie
+- - login: owlur
+ avatarUrl: https://avatars.githubusercontent.com/u/20010787?v=4
+ url: https://github.com/owlur
+ - login: Trivie
avatarUrl: https://avatars.githubusercontent.com/u/8161763?v=4
url: https://github.com/Trivie
- - login: americanair
avatarUrl: https://avatars.githubusercontent.com/u/12281813?v=4
url: https://github.com/americanair
- - login: 84adam
- avatarUrl: https://avatars.githubusercontent.com/u/13172004?u=293f3cc6bb7e6f6ecfcdd64489a3202468321254&v=4
- url: https://github.com/84adam
- login: CanoaPBC
avatarUrl: https://avatars.githubusercontent.com/u/64223768?v=4
url: https://github.com/CanoaPBC
- login: mainframeindustries
avatarUrl: https://avatars.githubusercontent.com/u/55092103?v=4
url: https://github.com/mainframeindustries
- - login: doseiai
- avatarUrl: https://avatars.githubusercontent.com/u/57115726?v=4
- url: https://github.com/doseiai
- login: AccentDesign
avatarUrl: https://avatars.githubusercontent.com/u/2429332?v=4
url: https://github.com/AccentDesign
@@ -104,15 +101,15 @@ sponsors:
- login: koconder
avatarUrl: https://avatars.githubusercontent.com/u/25068?u=582657b23622aaa3dfe68bd028a780f272f456fa&v=4
url: https://github.com/koconder
+ - login: b-rad-c
+ avatarUrl: https://avatars.githubusercontent.com/u/25362581?u=5bb10629f4015b62bec1f9a366675d5085551af9&v=4
+ url: https://github.com/b-rad-c
- login: ehaca
avatarUrl: https://avatars.githubusercontent.com/u/25950317?u=cec1a3e0643b785288ae8260cc295a85ab344995&v=4
url: https://github.com/ehaca
- login: timlrx
avatarUrl: https://avatars.githubusercontent.com/u/28362229?u=9a745ca31372ee324af682715ae88ce8522f9094&v=4
url: https://github.com/timlrx
- - login: mattmalcher
- avatarUrl: https://avatars.githubusercontent.com/u/31312775?v=4
- url: https://github.com/mattmalcher
- login: Leay15
avatarUrl: https://avatars.githubusercontent.com/u/32212558?u=c4aa9c1737e515959382a5515381757b1fd86c53&v=4
url: https://github.com/Leay15
@@ -137,6 +134,12 @@ sponsors:
- login: mjohnsey
avatarUrl: https://avatars.githubusercontent.com/u/16784016?u=38fad2e6b411244560b3af99c5f5a4751bc81865&v=4
url: https://github.com/mjohnsey
+ - login: ashi-agrawal
+ avatarUrl: https://avatars.githubusercontent.com/u/17105294?u=99c7a854035e5398d8e7b674f2d42baae6c957f8&v=4
+ url: https://github.com/ashi-agrawal
+ - login: sepsi77
+ avatarUrl: https://avatars.githubusercontent.com/u/18682303?v=4
+ url: https://github.com/sepsi77
- login: wedwardbeck
avatarUrl: https://avatars.githubusercontent.com/u/19333237?u=1de4ae2bf8d59eb4c013f21d863cbe0f2010575f&v=4
url: https://github.com/wedwardbeck
@@ -146,9 +149,12 @@ sponsors:
- login: Filimoa
avatarUrl: https://avatars.githubusercontent.com/u/21352040?u=0be845711495bbd7b756e13fcaeb8efc1ebd78ba&v=4
url: https://github.com/Filimoa
- - login: b-rad-c
- avatarUrl: https://avatars.githubusercontent.com/u/25362581?u=5bb10629f4015b62bec1f9a366675d5085551af9&v=4
- url: https://github.com/b-rad-c
+ - login: prodhype
+ avatarUrl: https://avatars.githubusercontent.com/u/60444672?u=3f278cff25ea37ead487d7861d4a984795de819e&v=4
+ url: https://github.com/prodhype
+ - login: yakkonaut
+ avatarUrl: https://avatars.githubusercontent.com/u/60633704?u=90a71fd631aa998ba4a96480788f017c9904e07b&v=4
+ url: https://github.com/yakkonaut
- login: patsatsia
avatarUrl: https://avatars.githubusercontent.com/u/61111267?u=3271b85f7a37b479c8d0ae0a235182e83c166edf&v=4
url: https://github.com/patsatsia
@@ -167,6 +173,9 @@ sponsors:
- login: apitally
avatarUrl: https://avatars.githubusercontent.com/u/138365043?v=4
url: https://github.com/apitally
+ - login: logic-automation
+ avatarUrl: https://avatars.githubusercontent.com/u/144732884?v=4
+ url: https://github.com/logic-automation
- login: thenickben
avatarUrl: https://avatars.githubusercontent.com/u/40610922?u=1e907d904041b7c91213951a3cb344cd37c14aaf&v=4
url: https://github.com/thenickben
@@ -179,12 +188,6 @@ sponsors:
- login: dudikbender
avatarUrl: https://avatars.githubusercontent.com/u/53487583?u=3a57542938ebfd57579a0111db2b297e606d9681&v=4
url: https://github.com/dudikbender
- - login: prodhype
- avatarUrl: https://avatars.githubusercontent.com/u/60444672?u=3f278cff25ea37ead487d7861d4a984795de819e&v=4
- url: https://github.com/prodhype
- - login: yakkonaut
- avatarUrl: https://avatars.githubusercontent.com/u/60633704?u=90a71fd631aa998ba4a96480788f017c9904e07b&v=4
- url: https://github.com/yakkonaut
- login: tcsmith
avatarUrl: https://avatars.githubusercontent.com/u/989034?u=7d8d741552b3279e8f4d3878679823a705a46f8f&v=4
url: https://github.com/tcsmith
@@ -233,9 +236,6 @@ sponsors:
- login: mintuhouse
avatarUrl: https://avatars.githubusercontent.com/u/769950?u=ecfbd79a97d33177e0d093ddb088283cf7fe8444&v=4
url: https://github.com/mintuhouse
- - login: simw
- avatarUrl: https://avatars.githubusercontent.com/u/6322526?v=4
- url: https://github.com/simw
- login: Rehket
avatarUrl: https://avatars.githubusercontent.com/u/7015688?u=3afb0ba200feebbc7f958950e92db34df2a3c172&v=4
url: https://github.com/Rehket
@@ -248,9 +248,9 @@ sponsors:
- login: wdwinslow
avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=dc01daafb354135603a263729e3d26d939c0c452&v=4
url: https://github.com/wdwinslow
- - login: drcat101
+ - login: catherinenelson1
avatarUrl: https://avatars.githubusercontent.com/u/11951946?u=e714b957185b8cf3d301cced7fc3ad2842122c6a&v=4
- url: https://github.com/drcat101
+ url: https://github.com/catherinenelson1
- login: zsinx6
avatarUrl: https://avatars.githubusercontent.com/u/3532625?u=ba75a5dc744d1116ccfeaaf30d41cb2fe81fe8dd&v=4
url: https://github.com/zsinx6
@@ -276,23 +276,26 @@ sponsors:
avatarUrl: https://avatars.githubusercontent.com/u/5300907?u=5b5452725ddb391b2caaebf34e05aba873591c3a&v=4
url: https://github.com/ennui93
- login: ternaus
- avatarUrl: https://avatars.githubusercontent.com/u/5481618?u=fabc8d75c921b3380126adb5a931c5da6e7db04f&v=4
+ avatarUrl: https://avatars.githubusercontent.com/u/5481618?u=513a26b02a39e7a28d587cd37c6cc877ea368e6e&v=4
url: https://github.com/ternaus
- login: eseglem
avatarUrl: https://avatars.githubusercontent.com/u/5920492?u=208d419cf667b8ac594c82a8db01932c7e50d057&v=4
url: https://github.com/eseglem
- - login: Yaleesa
- avatarUrl: https://avatars.githubusercontent.com/u/6135475?v=4
- url: https://github.com/Yaleesa
- login: FernandoCelmer
avatarUrl: https://avatars.githubusercontent.com/u/6262214?u=d29fff3fd862fda4ca752079f13f32e84c762ea4&v=4
url: https://github.com/FernandoCelmer
+ - login: simw
+ avatarUrl: https://avatars.githubusercontent.com/u/6322526?v=4
+ url: https://github.com/simw
- - login: getsentry
avatarUrl: https://avatars.githubusercontent.com/u/1396951?v=4
url: https://github.com/getsentry
- - login: pawamoy
avatarUrl: https://avatars.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4
url: https://github.com/pawamoy
+ - login: nisutec
+ avatarUrl: https://avatars.githubusercontent.com/u/25281462?u=e562484c451fdfc59053163f64405f8eb262b8b0&v=4
+ url: https://github.com/nisutec
- login: hoenie-ams
avatarUrl: https://avatars.githubusercontent.com/u/25708487?u=cda07434f0509ac728d9edf5e681117c0f6b818b&v=4
url: https://github.com/hoenie-ams
@@ -302,9 +305,6 @@ sponsors:
- login: rlnchow
avatarUrl: https://avatars.githubusercontent.com/u/28018479?u=a93ca9cf1422b9ece155784a72d5f2fdbce7adff&v=4
url: https://github.com/rlnchow
- - login: HosamAlmoghraby
- avatarUrl: https://avatars.githubusercontent.com/u/32025281?u=aa1b09feabccbf9dc506b81c71155f32d126cefa&v=4
- url: https://github.com/HosamAlmoghraby
- login: dvlpjrs
avatarUrl: https://avatars.githubusercontent.com/u/32254642?u=fbd6ad0324d4f1eb6231cf775be1c7bd4404e961&v=4
url: https://github.com/dvlpjrs
@@ -314,9 +314,9 @@ sponsors:
- login: bnkc
avatarUrl: https://avatars.githubusercontent.com/u/34930566?u=fa1dc8db3e920cf5c5636b97180a6f811fa01aaf&v=4
url: https://github.com/bnkc
- - login: curegit
- avatarUrl: https://avatars.githubusercontent.com/u/37978051?u=1733c322079118c0cdc573c03d92813f50a9faec&v=4
- url: https://github.com/curegit
+ - login: petercool
+ avatarUrl: https://avatars.githubusercontent.com/u/37613029?u=81c525232bb35780945a68e88afd96bb2cdad9c4&v=4
+ url: https://github.com/petercool
- login: JimFawkes
avatarUrl: https://avatars.githubusercontent.com/u/12075115?u=dc58ecfd064d72887c34bf500ddfd52592509acd&v=4
url: https://github.com/JimFawkes
@@ -341,12 +341,6 @@ sponsors:
- login: SebTota
avatarUrl: https://avatars.githubusercontent.com/u/25122511?v=4
url: https://github.com/SebTota
- - login: nisutec
- avatarUrl: https://avatars.githubusercontent.com/u/25281462?u=e562484c451fdfc59053163f64405f8eb262b8b0&v=4
- url: https://github.com/nisutec
- - login: 0417taehyun
- avatarUrl: https://avatars.githubusercontent.com/u/63915557?u=47debaa860fd52c9b98c97ef357ddcec3b3fb399&v=4
- url: https://github.com/0417taehyun
- login: fernandosmither
avatarUrl: https://avatars.githubusercontent.com/u/66154723?u=a76a037b5d674938a75d2cff862fb6dfd63ec214&v=4
url: https://github.com/fernandosmither
@@ -356,18 +350,15 @@ sponsors:
- login: PelicanQ
avatarUrl: https://avatars.githubusercontent.com/u/77930606?v=4
url: https://github.com/PelicanQ
- - login: tim-habitat
- avatarUrl: https://avatars.githubusercontent.com/u/86600518?u=7389dd77fe6a0eb8d13933356120b7d2b32d7bb4&v=4
- url: https://github.com/tim-habitat
- login: jugeeem
avatarUrl: https://avatars.githubusercontent.com/u/116043716?u=ae590d79c38ac79c91b9c5caa6887d061e865a3d&v=4
url: https://github.com/jugeeem
- login: tahmarrrr23
avatarUrl: https://avatars.githubusercontent.com/u/138208610?u=465a46b0ff72a74252d3e3a71ac7d2f1919cda28&v=4
url: https://github.com/tahmarrrr23
- - login: lukzmu
- avatarUrl: https://avatars.githubusercontent.com/u/155924127?u=2e52e40b3134bef370b52bf2e40a524f307c2a05&v=4
- url: https://github.com/lukzmu
+ - login: curegit
+ avatarUrl: https://avatars.githubusercontent.com/u/37978051?u=1733c322079118c0cdc573c03d92813f50a9faec&v=4
+ url: https://github.com/curegit
- login: kristiangronberg
avatarUrl: https://avatars.githubusercontent.com/u/42678548?v=4
url: https://github.com/kristiangronberg
@@ -377,9 +368,6 @@ sponsors:
- login: arrrrrmin
avatarUrl: https://avatars.githubusercontent.com/u/43553423?u=36a3880a6eb29309c19e6cadbb173bafbe91deb1&v=4
url: https://github.com/arrrrrmin
- - login: rbtrsv
- avatarUrl: https://avatars.githubusercontent.com/u/43938206?u=09955f324da271485a7edaf9241f449e88a1388a&v=4
- url: https://github.com/rbtrsv
- login: mobyw
avatarUrl: https://avatars.githubusercontent.com/u/44370805?v=4
url: https://github.com/mobyw
@@ -452,6 +440,9 @@ sponsors:
- login: moonape1226
avatarUrl: https://avatars.githubusercontent.com/u/8532038?u=d9f8b855a429fff9397c3833c2ff83849ebf989d&v=4
url: https://github.com/moonape1226
+ - login: msehnout
+ avatarUrl: https://avatars.githubusercontent.com/u/9369632?u=8c988f1b008a3f601385a3616f9327820f66e3a5&v=4
+ url: https://github.com/msehnout
- login: xncbf
avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=ee91e210ae93b9cdd8f248b21cb028316cc0b747&v=4
url: https://github.com/xncbf
@@ -489,7 +480,7 @@ sponsors:
avatarUrl: https://avatars.githubusercontent.com/u/5250987?u=4ed9a120c89805a8aefda1cbdc0cf6512e64d1b4&v=4
url: https://github.com/sdevkota
- login: brizzbuzz
- avatarUrl: https://avatars.githubusercontent.com/u/5607577?u=1ffbf39f5bb8736b75c0d235707d6e8f803725c5&v=4
+ avatarUrl: https://avatars.githubusercontent.com/u/5607577?u=58d5aae33bc97e52f11f334d2702e8710314b5c1&v=4
url: https://github.com/brizzbuzz
- login: Baghdady92
avatarUrl: https://avatars.githubusercontent.com/u/5708590?v=4
@@ -497,7 +488,10 @@ sponsors:
- login: jakeecolution
avatarUrl: https://avatars.githubusercontent.com/u/5884696?u=4a7c7883fb064b593b50cb6697b54687e6f7aafe&v=4
url: https://github.com/jakeecolution
-- - login: danburonline
+- - login: abizovnuralem
+ avatarUrl: https://avatars.githubusercontent.com/u/33475993?u=6ce72b11a16a8232d3dd1f958f460b4735f520d8&v=4
+ url: https://github.com/abizovnuralem
+ - login: danburonline
avatarUrl: https://avatars.githubusercontent.com/u/34251194?u=94935cccfbec58083ab1e535212d54f1bf2c978a&v=4
url: https://github.com/danburonline
- login: sadikkuzu
@@ -506,6 +500,12 @@ sponsors:
- login: rwxd
avatarUrl: https://avatars.githubusercontent.com/u/40308458?u=cd04a39e3655923be4f25c2ba8a5a07b3da3230a&v=4
url: https://github.com/rwxd
+ - login: YungBricoCoop
+ avatarUrl: https://avatars.githubusercontent.com/u/42273436?u=80470b400c416d1eabc2cc71b1efffc0e3503146&v=4
+ url: https://github.com/YungBricoCoop
+ - login: nlazaro
+ avatarUrl: https://avatars.githubusercontent.com/u/44237350?u=939a570fc965d93e9db1284b5acc173c1a0be4a0&v=4
+ url: https://github.com/nlazaro
- login: Patechoc
avatarUrl: https://avatars.githubusercontent.com/u/2376641?u=23b49e9eda04f078cb74fa3f93593aa6a57bb138&v=4
url: https://github.com/Patechoc
diff --git a/docs/en/data/people.yml b/docs/en/data/people.yml
index 710c650fd..cc5479c82 100644
--- a/docs/en/data/people.yml
+++ b/docs/en/data/people.yml
@@ -1,12 +1,12 @@
maintainers:
- login: tiangolo
answers: 1878
- prs: 550
+ prs: 559
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=740f11212a731f56798f558ceddb0bd07642afa7&v=4
url: https://github.com/tiangolo
experts:
- login: Kludex
- count: 596
+ count: 598
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
- login: dmontagu
@@ -14,7 +14,7 @@ experts:
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=540f30c937a6450812628b9592a1dfe91bbe148e&v=4
url: https://github.com/dmontagu
- login: jgould22
- count: 232
+ count: 235
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
- login: Mause
@@ -23,7 +23,7 @@ experts:
url: https://github.com/Mause
- login: ycd
count: 217
- avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=bba5af018423a2858d49309bed2a899bb5c34ac5&v=4
+ avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=45aa6ef58220a3f1e8a3c3cd5f1b75a1a0a73347&v=4
url: https://github.com/ycd
- login: JarroVGIT
count: 193
@@ -58,7 +58,7 @@ experts:
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=ad9838e089058c9e5a0bab94c0eec7cc181e0cd0&v=4
url: https://github.com/falkben
- login: JavierSanchezCastro
- count: 52
+ count: 55
avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
url: https://github.com/JavierSanchezCastro
- login: n8sty
@@ -77,10 +77,6 @@ experts:
count: 47
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
url: https://github.com/acidjunk
-- login: Dustyposa
- count: 45
- avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
- url: https://github.com/Dustyposa
- login: adriangb
count: 45
avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=612704256e38d6ac9cbed24f10e4b6ac2da74ecb&v=4
@@ -89,6 +85,14 @@ experts:
count: 45
avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
url: https://github.com/insomnes
+- login: Dustyposa
+ count: 45
+ avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
+ url: https://github.com/Dustyposa
+- login: YuriiMotov
+ count: 43
+ avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
+ url: https://github.com/YuriiMotov
- login: frankie567
count: 43
avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=c159fe047727aedecbbeeaa96a1b03ceb9d39add&v=4
@@ -129,10 +133,6 @@ experts:
count: 25
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
url: https://github.com/wshayes
-- login: YuriiMotov
- count: 24
- avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
- url: https://github.com/YuriiMotov
- login: acnebs
count: 23
avatarUrl: https://avatars.githubusercontent.com/u/9054108?v=4
@@ -153,6 +153,10 @@ experts:
count: 21
avatarUrl: https://avatars.githubusercontent.com/u/51059348?u=5fe59a56e1f2f9ccd8005d71752a8276f133ae1a&v=4
url: https://github.com/rafsaf
+- login: hasansezertasan
+ count: 20
+ avatarUrl: https://avatars.githubusercontent.com/u/13135006?u=99f0b0f0fc47e88e8abb337b4447357939ef93e7&v=4
+ url: https://github.com/hasansezertasan
- login: nsidnev
count: 20
avatarUrl: https://avatars.githubusercontent.com/u/22559461?u=a9cc3238217e21dc8796a1a500f01b722adb082c&v=4
@@ -165,10 +169,6 @@ experts:
count: 20
avatarUrl: https://avatars.githubusercontent.com/u/565544?v=4
url: https://github.com/chris-allnutt
-- login: hasansezertasan
- count: 19
- avatarUrl: https://avatars.githubusercontent.com/u/13135006?u=99f0b0f0fc47e88e8abb337b4447357939ef93e7&v=4
- url: https://github.com/hasansezertasan
- login: retnikt
count: 18
avatarUrl: https://avatars.githubusercontent.com/u/24581770?v=4
@@ -177,6 +177,10 @@ experts:
count: 18
avatarUrl: https://avatars.githubusercontent.com/u/22326718?u=31ba446ac290e23e56eea8e4f0c558aaf0b40779&v=4
url: https://github.com/zoliknemet
+- login: nkhitrov
+ count: 17
+ avatarUrl: https://avatars.githubusercontent.com/u/28262306?u=66ee21316275ef356081c2efc4ed7a4572e690dc&v=4
+ url: https://github.com/nkhitrov
- login: Hultner
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/2669034?u=115e53df959309898ad8dc9443fbb35fee71df07&v=4
@@ -185,10 +189,6 @@ experts:
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/1765494?u=5b1ab7c582db4b4016fa31affe977d10af108ad4&v=4
url: https://github.com/harunyasar
-- login: nkhitrov
- count: 17
- avatarUrl: https://avatars.githubusercontent.com/u/28262306?u=66ee21316275ef356081c2efc4ed7a4572e690dc&v=4
- url: https://github.com/nkhitrov
- login: caeser1996
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/16540232?u=05d2beb8e034d584d0a374b99d8826327bd7f614&v=4
@@ -199,41 +199,41 @@ experts:
url: https://github.com/jonatasoli
last_month_experts:
- login: YuriiMotov
- count: 24
+ count: 40
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
url: https://github.com/YuriiMotov
-- login: Kludex
- count: 17
- avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
- url: https://github.com/Kludex
- login: JavierSanchezCastro
- count: 13
+ count: 11
avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
url: https://github.com/JavierSanchezCastro
+- login: Kludex
+ count: 8
+ avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
+ url: https://github.com/Kludex
- login: jgould22
- count: 11
+ count: 7
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
-- login: GodMoonGoodman
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/29688727?u=7b251da620d999644c37c1feeb292d033eed7ad6&v=4
- url: https://github.com/GodMoonGoodman
-- login: n8sty
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4
- url: https://github.com/n8sty
-- login: flo-at
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/564288?v=4
- url: https://github.com/flo-at
-- login: estebanx64
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/10840422?u=45f015f95e1c0f06df602be4ab688d4b854cc8a8&v=4
- url: https://github.com/estebanx64
-- login: ahmedabdou14
+- login: omarcruzpantoja
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/15116058?u=4b64c643fad49225d854e1aaecd1ffc6f9071a1b&v=4
+ url: https://github.com/omarcruzpantoja
+- login: pythonweb2
count: 2
- avatarUrl: https://avatars.githubusercontent.com/u/104530599?u=05365b155a1ff911532e8be316acfad2e0736f98&v=4
- url: https://github.com/ahmedabdou14
+ avatarUrl: https://avatars.githubusercontent.com/u/32141163?v=4
+ url: https://github.com/pythonweb2
+- login: PhysicallyActive
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/160476156?u=7a8e44f4a43d3bba636f795bb7d9476c9233b4d8&v=4
+ url: https://github.com/PhysicallyActive
+- login: VatsalJagani
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/20964366?u=43552644be05c9107c029e26d5ab3be5a1920f45&v=4
+ url: https://github.com/VatsalJagani
+- login: khaledadrani
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/45245894?u=49ed5056426a149a5af29d385d8bd3847101d3a4&v=4
+ url: https://github.com/khaledadrani
- login: chrisK824
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/79946379?u=03d85b22d696a58a9603e55fbbbe2de6b0f4face&v=4
@@ -242,41 +242,33 @@ last_month_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/50728601?u=167c0bd655e52817082e50979a86d2f98f95b1a3&v=4
url: https://github.com/ThirVondukr
-- login: richin13
- count: 2
- avatarUrl: https://avatars.githubusercontent.com/u/8370058?u=8e37a4cdbc78983a5f4b4847f6d1879fb39c851c&v=4
- url: https://github.com/richin13
- login: hussein-awala
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/21311487?u=cbbc60943d3fedfb869e49b604020a821f589659&v=4
url: https://github.com/hussein-awala
-- login: admo1
- count: 2
- avatarUrl: https://avatars.githubusercontent.com/u/14835916?v=4
- url: https://github.com/admo1
three_months_experts:
- login: Kludex
- count: 90
+ count: 84
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
-- login: JavierSanchezCastro
- count: 28
- avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
- url: https://github.com/JavierSanchezCastro
-- login: jgould22
- count: 28
- avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
- url: https://github.com/jgould22
- login: YuriiMotov
- count: 24
+ count: 43
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
url: https://github.com/YuriiMotov
+- login: jgould22
+ count: 30
+ avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
+ url: https://github.com/jgould22
+- login: JavierSanchezCastro
+ count: 24
+ avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
+ url: https://github.com/JavierSanchezCastro
- login: n8sty
- count: 12
+ count: 11
avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4
url: https://github.com/n8sty
- login: hasansezertasan
- count: 12
+ count: 8
avatarUrl: https://avatars.githubusercontent.com/u/13135006?u=99f0b0f0fc47e88e8abb337b4447357939ef93e7&v=4
url: https://github.com/hasansezertasan
- login: dolfinus
@@ -287,14 +279,6 @@ three_months_experts:
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/2835374?u=3c3ed29aa8b09ccaf8d66def0ce82bc2f7e5aab6&v=4
url: https://github.com/aanchlia
-- login: Ventura94
- count: 6
- avatarUrl: https://avatars.githubusercontent.com/u/43103937?u=ccb837005aaf212a449c374618c4339089e2f733&v=4
- url: https://github.com/Ventura94
-- login: shashstormer
- count: 5
- avatarUrl: https://avatars.githubusercontent.com/u/90090313?v=4
- url: https://github.com/shashstormer
- login: GodMoonGoodman
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/29688727?u=7b251da620d999644c37c1feeb292d033eed7ad6&v=4
@@ -307,6 +291,14 @@ three_months_experts:
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/10840422?u=45f015f95e1c0f06df602be4ab688d4b854cc8a8&v=4
url: https://github.com/estebanx64
+- login: omarcruzpantoja
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/15116058?u=4b64c643fad49225d854e1aaecd1ffc6f9071a1b&v=4
+ url: https://github.com/omarcruzpantoja
+- login: fmelihh
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/99879453?u=f76c4460556e41a59eb624acd0cf6e342d660700&v=4
+ url: https://github.com/fmelihh
- login: ahmedabdou14
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/104530599?u=05365b155a1ff911532e8be316acfad2e0736f98&v=4
@@ -315,10 +307,26 @@ three_months_experts:
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/79946379?u=03d85b22d696a58a9603e55fbbbe2de6b0f4face&v=4
url: https://github.com/chrisK824
-- login: fmelihh
- count: 3
- avatarUrl: https://avatars.githubusercontent.com/u/99879453?u=f76c4460556e41a59eb624acd0cf6e342d660700&v=4
- url: https://github.com/fmelihh
+- login: pythonweb2
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/32141163?v=4
+ url: https://github.com/pythonweb2
+- login: PhysicallyActive
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/160476156?u=7a8e44f4a43d3bba636f795bb7d9476c9233b4d8&v=4
+ url: https://github.com/PhysicallyActive
+- login: richin13
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/8370058?u=8e37a4cdbc78983a5f4b4847f6d1879fb39c851c&v=4
+ url: https://github.com/richin13
+- login: VatsalJagani
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/20964366?u=43552644be05c9107c029e26d5ab3be5a1920f45&v=4
+ url: https://github.com/VatsalJagani
+- login: khaledadrani
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/45245894?u=49ed5056426a149a5af29d385d8bd3847101d3a4&v=4
+ url: https://github.com/khaledadrani
- login: acidjunk
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
@@ -331,10 +339,6 @@ three_months_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/50728601?u=167c0bd655e52817082e50979a86d2f98f95b1a3&v=4
url: https://github.com/ThirVondukr
-- login: richin13
- count: 2
- avatarUrl: https://avatars.githubusercontent.com/u/8370058?u=8e37a4cdbc78983a5f4b4847f6d1879fb39c851c&v=4
- url: https://github.com/richin13
- login: hussein-awala
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/21311487?u=cbbc60943d3fedfb869e49b604020a821f589659&v=4
@@ -375,10 +379,6 @@ three_months_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/78362619?u=fe6e8d05f94d8d4c0679a4da943955a686f96177&v=4
url: https://github.com/DJoepie
-- login: alex-pobeditel-2004
- count: 2
- avatarUrl: https://avatars.githubusercontent.com/u/14791483?v=4
- url: https://github.com/alex-pobeditel-2004
- login: binbjz
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/8213913?u=22b68b7a0d5bf5e09c02084c0f5f53d7503114cd&v=4
@@ -391,14 +391,6 @@ three_months_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/7178184?v=4
url: https://github.com/TarasKuzyo
-- login: kiraware
- count: 2
- avatarUrl: https://avatars.githubusercontent.com/u/117554978?v=4
- url: https://github.com/kiraware
-- login: iudeen
- count: 2
- avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
- url: https://github.com/iudeen
- login: msehnout
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/9369632?u=8c988f1b008a3f601385a3616f9327820f66e3a5&v=4
@@ -415,43 +407,39 @@ three_months_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/8787120?u=7028d2b3a2a26534c1806eb76c7425a3fac9732f&v=4
url: https://github.com/garg10may
-- login: taegyunum
- count: 2
- avatarUrl: https://avatars.githubusercontent.com/u/16094650?v=4
- url: https://github.com/taegyunum
six_months_experts:
- login: Kludex
- count: 112
+ count: 108
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
- login: jgould22
- count: 66
+ count: 67
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
-- login: JavierSanchezCastro
- count: 32
- avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
- url: https://github.com/JavierSanchezCastro
- login: YuriiMotov
- count: 24
+ count: 43
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
url: https://github.com/YuriiMotov
+- login: JavierSanchezCastro
+ count: 35
+ avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
+ url: https://github.com/JavierSanchezCastro
- login: n8sty
- count: 24
+ count: 21
avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4
url: https://github.com/n8sty
- login: hasansezertasan
- count: 19
+ count: 20
avatarUrl: https://avatars.githubusercontent.com/u/13135006?u=99f0b0f0fc47e88e8abb337b4447357939ef93e7&v=4
url: https://github.com/hasansezertasan
- login: WilliamStam
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/182800?v=4
url: https://github.com/WilliamStam
-- login: iudeen
+- login: pythonweb2
count: 6
- avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
- url: https://github.com/iudeen
+ avatarUrl: https://avatars.githubusercontent.com/u/32141163?v=4
+ url: https://github.com/pythonweb2
- login: dolfinus
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/4661021?u=a51b39001a2e5e7529b45826980becf786de2327&v=4
@@ -464,22 +452,14 @@ six_months_experts:
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/43103937?u=ccb837005aaf212a449c374618c4339089e2f733&v=4
url: https://github.com/Ventura94
-- login: nymous
- count: 6
- avatarUrl: https://avatars.githubusercontent.com/u/4216559?u=360a36fb602cded27273cbfc0afc296eece90662&v=4
- url: https://github.com/nymous
- login: White-Mask
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/31826970?u=8625355dc25ddf9c85a8b2b0b9932826c4c8f44c&v=4
url: https://github.com/White-Mask
-- login: chrisK824
+- login: nymous
count: 5
- avatarUrl: https://avatars.githubusercontent.com/u/79946379?u=03d85b22d696a58a9603e55fbbbe2de6b0f4face&v=4
- url: https://github.com/chrisK824
-- login: alex-pobeditel-2004
- count: 5
- avatarUrl: https://avatars.githubusercontent.com/u/14791483?v=4
- url: https://github.com/alex-pobeditel-2004
+ avatarUrl: https://avatars.githubusercontent.com/u/4216559?u=360a36fb602cded27273cbfc0afc296eece90662&v=4
+ url: https://github.com/nymous
- login: shashstormer
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/90090313?v=4
@@ -496,26 +476,30 @@ six_months_experts:
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/564288?v=4
url: https://github.com/flo-at
-- login: ebottos94
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/100039558?u=e2c672da5a7977fd24d87ce6ab35f8bf5b1ed9fa&v=4
- url: https://github.com/ebottos94
- login: estebanx64
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/10840422?u=45f015f95e1c0f06df602be4ab688d4b854cc8a8&v=4
url: https://github.com/estebanx64
-- login: pythonweb2
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/32141163?v=4
- url: https://github.com/pythonweb2
-- login: ahmedabdou14
+- login: omarcruzpantoja
count: 3
- avatarUrl: https://avatars.githubusercontent.com/u/104530599?u=05365b155a1ff911532e8be316acfad2e0736f98&v=4
- url: https://github.com/ahmedabdou14
+ avatarUrl: https://avatars.githubusercontent.com/u/15116058?u=4b64c643fad49225d854e1aaecd1ffc6f9071a1b&v=4
+ url: https://github.com/omarcruzpantoja
- login: fmelihh
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/99879453?u=f76c4460556e41a59eb624acd0cf6e342d660700&v=4
url: https://github.com/fmelihh
+- login: ahmedabdou14
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/104530599?u=05365b155a1ff911532e8be316acfad2e0736f98&v=4
+ url: https://github.com/ahmedabdou14
+- login: chrisK824
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/79946379?u=03d85b22d696a58a9603e55fbbbe2de6b0f4face&v=4
+ url: https://github.com/chrisK824
+- login: ebottos94
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/100039558?u=e2c672da5a7977fd24d87ce6ab35f8bf5b1ed9fa&v=4
+ url: https://github.com/ebottos94
- login: binbjz
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/8213913?u=22b68b7a0d5bf5e09c02084c0f5f53d7503114cd&v=4
@@ -524,18 +508,10 @@ six_months_experts:
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/16098190?u=dc70db88a7a99b764c9a89a6e471e0b7ca478a35&v=4
url: https://github.com/theobouwman
-- login: Ryandaydev
- count: 3
- avatarUrl: https://avatars.githubusercontent.com/u/4292423?u=48f68868db8886fce31a1d802c1003914c6cd7c6&v=4
- url: https://github.com/Ryandaydev
- login: sriram-kondakindi
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/32274323?v=4
url: https://github.com/sriram-kondakindi
-- login: NeilBotelho
- count: 3
- avatarUrl: https://avatars.githubusercontent.com/u/39030675?u=16fea2ff90a5c67b974744528a38832a6d1bb4f7&v=4
- url: https://github.com/NeilBotelho
- login: yinziyan1206
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/37829370?u=da44ca53aefd5c23f346fab8e9fd2e108294c179&v=4
@@ -544,14 +520,54 @@ six_months_experts:
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/48502122?u=89fe3e55f3cfd15d34ffac239b32af358cca6481&v=4
url: https://github.com/pcorvoh
+- login: osangu
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/80697064?u=de9bae685e2228bffd4e202274e1df1afaf54a0d&v=4
+ url: https://github.com/osangu
+- login: PhysicallyActive
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/160476156?u=7a8e44f4a43d3bba636f795bb7d9476c9233b4d8&v=4
+ url: https://github.com/PhysicallyActive
+- login: richin13
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/8370058?u=8e37a4cdbc78983a5f4b4847f6d1879fb39c851c&v=4
+ url: https://github.com/richin13
+- login: amacfie
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/889657?u=d70187989940b085bcbfa3bedad8dbc5f3ab1fe7&v=4
+ url: https://github.com/amacfie
+- login: WSH032
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/126865849?v=4
+ url: https://github.com/WSH032
+- login: MRigal
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/2190327?u=557f399ee90319da7bc4a7d9274e110836b0bd60&v=4
+ url: https://github.com/MRigal
+- login: VatsalJagani
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/20964366?u=43552644be05c9107c029e26d5ab3be5a1920f45&v=4
+ url: https://github.com/VatsalJagani
+- login: nameer
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/3931725?u=6199fb065df098fc13ac0a5e649f89672b586732&v=4
+ url: https://github.com/nameer
+- login: kiraware
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/117554978?v=4
+ url: https://github.com/kiraware
+- login: iudeen
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
+ url: https://github.com/iudeen
+- login: khaledadrani
+ count: 2
+ avatarUrl: https://avatars.githubusercontent.com/u/45245894?u=49ed5056426a149a5af29d385d8bd3847101d3a4&v=4
+ url: https://github.com/khaledadrani
- login: acidjunk
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
url: https://github.com/acidjunk
-- login: shashiwtt
- count: 2
- avatarUrl: https://avatars.githubusercontent.com/u/87797476?v=4
- url: https://github.com/shashiwtt
- login: yavuzakyazici
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/148442912?u=1d2d150172c53daf82020b950c6483a6c6a77b7e&v=4
@@ -568,10 +584,6 @@ six_months_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/50728601?u=167c0bd655e52817082e50979a86d2f98f95b1a3&v=4
url: https://github.com/ThirVondukr
-- login: richin13
- count: 2
- avatarUrl: https://avatars.githubusercontent.com/u/8370058?u=8e37a4cdbc78983a5f4b4847f6d1879fb39c851c&v=4
- url: https://github.com/richin13
- login: hussein-awala
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/21311487?u=cbbc60943d3fedfb869e49b604020a821f589659&v=4
@@ -580,10 +592,6 @@ six_months_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/996689?v=4
url: https://github.com/jcphlux
-- login: Matthieu-LAURENT39
- count: 2
- avatarUrl: https://avatars.githubusercontent.com/u/91389613?v=4
- url: https://github.com/Matthieu-LAURENT39
- login: bhumkong
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/13270137?u=1490432e6a0184fbc3d5c8d1b5df553ca92e7e5b&v=4
@@ -596,95 +604,79 @@ six_months_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/1032980?u=722c96b0a234752df23f04df150ef36441ceb43c&v=4
url: https://github.com/mielvds
-- login: admo1
- count: 2
- avatarUrl: https://avatars.githubusercontent.com/u/14835916?v=4
- url: https://github.com/admo1
-- login: pbasista
- count: 2
- avatarUrl: https://avatars.githubusercontent.com/u/1535892?u=e9a8bd5b3b2f95340cfeb4bc97886e9334911669&v=4
- url: https://github.com/pbasista
-- login: osangu
- count: 2
- avatarUrl: https://avatars.githubusercontent.com/u/80697064?u=de9bae685e2228bffd4e202274e1df1afaf54a0d&v=4
- url: https://github.com/osangu
-- login: bogdan-coman-uv
- count: 2
- avatarUrl: https://avatars.githubusercontent.com/u/92912507?v=4
- url: https://github.com/bogdan-coman-uv
-- login: leonidktoto
- count: 2
- avatarUrl: https://avatars.githubusercontent.com/u/159561986?v=4
- url: https://github.com/leonidktoto
one_year_experts:
- login: Kludex
- count: 231
+ count: 218
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
- login: jgould22
- count: 132
+ count: 133
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
- login: JavierSanchezCastro
- count: 52
+ count: 55
avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
url: https://github.com/JavierSanchezCastro
-- login: n8sty
- count: 39
- avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4
- url: https://github.com/n8sty
- login: YuriiMotov
- count: 24
+ count: 43
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
url: https://github.com/YuriiMotov
+- login: n8sty
+ count: 37
+ avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4
+ url: https://github.com/n8sty
- login: chrisK824
count: 22
avatarUrl: https://avatars.githubusercontent.com/u/79946379?u=03d85b22d696a58a9603e55fbbbe2de6b0f4face&v=4
url: https://github.com/chrisK824
- login: hasansezertasan
- count: 19
+ count: 20
avatarUrl: https://avatars.githubusercontent.com/u/13135006?u=99f0b0f0fc47e88e8abb337b4447357939ef93e7&v=4
url: https://github.com/hasansezertasan
-- login: abhint
- count: 14
- avatarUrl: https://avatars.githubusercontent.com/u/25699289?u=b5d219277b4d001ac26fb8be357fddd88c29d51b&v=4
- url: https://github.com/abhint
-- login: ahmedabdou14
- count: 13
- avatarUrl: https://avatars.githubusercontent.com/u/104530599?u=05365b155a1ff911532e8be316acfad2e0736f98&v=4
- url: https://github.com/ahmedabdou14
- login: nymous
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/4216559?u=360a36fb602cded27273cbfc0afc296eece90662&v=4
url: https://github.com/nymous
-- login: iudeen
+- login: ahmedabdou14
+ count: 13
+ avatarUrl: https://avatars.githubusercontent.com/u/104530599?u=05365b155a1ff911532e8be316acfad2e0736f98&v=4
+ url: https://github.com/ahmedabdou14
+- login: abhint
count: 12
- avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
- url: https://github.com/iudeen
+ avatarUrl: https://avatars.githubusercontent.com/u/25699289?u=b5d219277b4d001ac26fb8be357fddd88c29d51b&v=4
+ url: https://github.com/abhint
- login: arjwilliams
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/22227620?v=4
url: https://github.com/arjwilliams
-- login: ebottos94
- count: 10
- avatarUrl: https://avatars.githubusercontent.com/u/100039558?u=e2c672da5a7977fd24d87ce6ab35f8bf5b1ed9fa&v=4
- url: https://github.com/ebottos94
-- login: Viicos
- count: 10
- avatarUrl: https://avatars.githubusercontent.com/u/65306057?u=fcd677dc1b9bef12aa103613e5ccb3f8ce305af9&v=4
- url: https://github.com/Viicos
+- login: iudeen
+ count: 11
+ avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
+ url: https://github.com/iudeen
- login: WilliamStam
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/182800?v=4
url: https://github.com/WilliamStam
- login: yinziyan1206
- count: 10
+ count: 9
avatarUrl: https://avatars.githubusercontent.com/u/37829370?u=da44ca53aefd5c23f346fab8e9fd2e108294c179&v=4
url: https://github.com/yinziyan1206
- login: mateoradman
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/48420316?u=066f36b8e8e263b0d90798113b0f291d3266db7c&v=4
url: https://github.com/mateoradman
+- login: Viicos
+ count: 7
+ avatarUrl: https://avatars.githubusercontent.com/u/65306057?u=fcd677dc1b9bef12aa103613e5ccb3f8ce305af9&v=4
+ url: https://github.com/Viicos
+- login: pythonweb2
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/32141163?v=4
+ url: https://github.com/pythonweb2
+- login: ebottos94
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/100039558?u=e2c672da5a7977fd24d87ce6ab35f8bf5b1ed9fa&v=4
+ url: https://github.com/ebottos94
- login: dolfinus
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/4661021?u=a51b39001a2e5e7529b45826980becf786de2327&v=4
@@ -733,14 +725,14 @@ one_year_experts:
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/52145145?u=f8c9e5c8c259d248e1683fedf5027b4ee08a0967&v=4
url: https://github.com/wu-clan
-- login: adriangb
- count: 5
- avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=612704256e38d6ac9cbed24f10e4b6ac2da74ecb&v=4
- url: https://github.com/adriangb
- login: 8thgencore
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/30128845?u=a747e840f751a1d196d70d0ecf6d07a530d412a1&v=4
url: https://github.com/8thgencore
+- login: anthonycepeda
+ count: 4
+ avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=60bdf46240cff8fca482ff0fc07d963fd5e1a27c&v=4
+ url: https://github.com/anthonycepeda
- login: acidjunk
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
@@ -773,53 +765,49 @@ one_year_experts:
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/977953?u=d94445b7b87b7096a92a2d4b652ca6c560f34039&v=4
url: https://github.com/sanzoghenzo
-- login: hochstibe
+- login: adriangb
count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/48712216?u=1862e0265e06be7ff710f7dc12094250c0616313&v=4
- url: https://github.com/hochstibe
-- login: pythonweb2
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/32141163?v=4
- url: https://github.com/pythonweb2
-- login: nameer
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/3931725?u=6199fb065df098fc13ac0a5e649f89672b586732&v=4
- url: https://github.com/nameer
-- login: anthonycepeda
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=60bdf46240cff8fca482ff0fc07d963fd5e1a27c&v=4
- url: https://github.com/anthonycepeda
+ avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=612704256e38d6ac9cbed24f10e4b6ac2da74ecb&v=4
+ url: https://github.com/adriangb
- login: 9en9i
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/44907258?u=297d0f31ea99c22b718118c1deec82001690cadb&v=4
url: https://github.com/9en9i
-- login: AlexanderPodorov
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/54511144?v=4
- url: https://github.com/AlexanderPodorov
-- login: sharonyogev
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/31185192?u=b13ea64b3cdaf3903390c555793aba4aff45c5e6&v=4
- url: https://github.com/sharonyogev
-- login: fmelihh
- count: 3
- avatarUrl: https://avatars.githubusercontent.com/u/99879453?u=f76c4460556e41a59eb624acd0cf6e342d660700&v=4
- url: https://github.com/fmelihh
-- login: jinluyang
- count: 3
- avatarUrl: https://avatars.githubusercontent.com/u/15670327?v=4
- url: https://github.com/jinluyang
- login: mht2953658596
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/59814105?v=4
url: https://github.com/mht2953658596
+- login: omarcruzpantoja
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/15116058?u=4b64c643fad49225d854e1aaecd1ffc6f9071a1b&v=4
+ url: https://github.com/omarcruzpantoja
+- login: fmelihh
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/99879453?u=f76c4460556e41a59eb624acd0cf6e342d660700&v=4
+ url: https://github.com/fmelihh
+- login: amacfie
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/889657?u=d70187989940b085bcbfa3bedad8dbc5f3ab1fe7&v=4
+ url: https://github.com/amacfie
+- login: nameer
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/3931725?u=6199fb065df098fc13ac0a5e649f89672b586732&v=4
+ url: https://github.com/nameer
+- login: hhartzer
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/100533792?v=4
+ url: https://github.com/hhartzer
+- login: binbjz
+ count: 3
+ avatarUrl: https://avatars.githubusercontent.com/u/8213913?u=22b68b7a0d5bf5e09c02084c0f5f53d7503114cd&v=4
+ url: https://github.com/binbjz
top_contributors:
- login: nilslindemann
- count: 30
+ count: 127
avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4
url: https://github.com/nilslindemann
- login: jaystone776
- count: 27
+ count: 49
avatarUrl: https://avatars.githubusercontent.com/u/11191137?u=299205a95e9b6817a43144a48b643346a5aac5cc&v=4
url: https://github.com/jaystone776
- login: waynerv
@@ -827,7 +815,7 @@ top_contributors:
avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
url: https://github.com/waynerv
- login: tokusumi
- count: 23
+ count: 24
avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
url: https://github.com/tokusumi
- login: Kludex
@@ -870,6 +858,10 @@ top_contributors:
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
url: https://github.com/hard-coders
+- login: alejsdev
+ count: 10
+ avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=1ee3a9fbef27abc9448ef5951350f99c7d76f7af&v=4
+ url: https://github.com/alejsdev
- login: KaniKim
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/19832624?u=d8ff6fca8542d22f94388cd2c4292e76e3898584&v=4
@@ -906,10 +898,6 @@ top_contributors:
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/33462923?u=0fb3d7acb316764616f11e4947faf080e49ad8d9&v=4
url: https://github.com/batlopes
-- login: alejsdev
- count: 6
- avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=1ee3a9fbef27abc9448ef5951350f99c7d76f7af&v=4
- url: https://github.com/alejsdev
- login: wshayes
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
@@ -944,7 +932,7 @@ top_contributors:
url: https://github.com/jfunez
- login: ycd
count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=bba5af018423a2858d49309bed2a899bb5c34ac5&v=4
+ avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=45aa6ef58220a3f1e8a3c3cd5f1b75a1a0a73347&v=4
url: https://github.com/ycd
- login: komtaki
count: 4
@@ -1000,7 +988,7 @@ top_contributors:
url: https://github.com/pawamoy
top_reviewers:
- login: Kludex
- count: 155
+ count: 156
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
- login: BilalAlpaslan
@@ -1033,7 +1021,7 @@ top_reviewers:
url: https://github.com/Laineyzhang55
- login: ycd
count: 45
- avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=bba5af018423a2858d49309bed2a899bb5c34ac5&v=4
+ avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=45aa6ef58220a3f1e8a3c3cd5f1b75a1a0a73347&v=4
url: https://github.com/ycd
- login: cikay
count: 41
@@ -1079,6 +1067,10 @@ top_reviewers:
count: 24
avatarUrl: https://avatars.githubusercontent.com/u/16273730?u=095b66f243a2cd6a0aadba9a095009f8aaf18393&v=4
url: https://github.com/LorhanSohaky
+- login: YuriiMotov
+ count: 24
+ avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
+ url: https://github.com/YuriiMotov
- login: dmontagu
count: 23
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=540f30c937a6450812628b9592a1dfe91bbe148e&v=4
@@ -1091,10 +1083,6 @@ top_reviewers:
count: 23
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
url: https://github.com/hard-coders
-- login: YuriiMotov
- count: 23
- avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
- url: https://github.com/YuriiMotov
- login: rjNemo
count: 21
avatarUrl: https://avatars.githubusercontent.com/u/56785022?u=d5c3a02567c8649e146fcfc51b6060ccaf8adef8&v=4
@@ -1155,6 +1143,10 @@ top_reviewers:
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/6478810?u=af15d724875cec682ed8088a86d36b2798f981c0&v=4
url: https://github.com/sh0nk
+- login: junah201
+ count: 13
+ avatarUrl: https://avatars.githubusercontent.com/u/75025529?u=2451c256e888fa2a06bcfc0646d09b87ddb6a945&v=4
+ url: https://github.com/junah201
- login: wdh99
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/108172295?u=8a8fb95d5afe3e0fa33257b2aecae88d436249eb&v=4
@@ -1191,19 +1183,15 @@ top_reviewers:
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
url: https://github.com/mariacamilagl
-- login: raphaelauv
- count: 10
- avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
- url: https://github.com/raphaelauv
top_translations_reviewers:
+- login: s111d
+ count: 143
+ avatarUrl: https://avatars.githubusercontent.com/u/4954856?v=4
+ url: https://github.com/s111d
- login: Xewus
count: 128
avatarUrl: https://avatars.githubusercontent.com/u/85196001?u=f8e2dc7e5104f109cef944af79050ea8d1b8f914&v=4
url: https://github.com/Xewus
-- login: s111d
- count: 122
- avatarUrl: https://avatars.githubusercontent.com/u/4954856?v=4
- url: https://github.com/s111d
- login: tokusumi
count: 104
avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
@@ -1250,7 +1238,7 @@ top_translations_reviewers:
url: https://github.com/solomein-sv
- login: alperiox
count: 37
- avatarUrl: https://avatars.githubusercontent.com/u/34214152?u=0688c1dc00988150a82d299106062c062ed1ba13&v=4
+ avatarUrl: https://avatars.githubusercontent.com/u/34214152?u=2c5acad3461d4dbc2d48371ba86cac56ae9b25cc&v=4
url: https://github.com/alperiox
- login: lsglucas
count: 36
@@ -1342,7 +1330,7 @@ top_translations_reviewers:
url: https://github.com/Attsun1031
- login: ycd
count: 20
- avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=bba5af018423a2858d49309bed2a899bb5c34ac5&v=4
+ avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=45aa6ef58220a3f1e8a3c3cd5f1b75a1a0a73347&v=4
url: https://github.com/ycd
- login: delhi09
count: 20
diff --git a/docs/en/docs/advanced/generate-clients.md b/docs/en/docs/advanced/generate-clients.md
index 3a810baee..c333ddf85 100644
--- a/docs/en/docs/advanced/generate-clients.md
+++ b/docs/en/docs/advanced/generate-clients.md
@@ -10,7 +10,7 @@ There are many tools to generate clients from **OpenAPI**.
A common tool is
```console
-$ npm install openapi-typescript-codegen --save-dev
+$ npm install @hey-api/openapi-ts --save-dev
---> 100%
```
@@ -74,7 +74,7 @@ $ npm install openapi-typescript-codegen --save-dev
#### Generate Client Code
-To generate the client code you can use the command line application `openapi` that would now be installed.
+To generate the client code you can use the command line application `openapi-ts` that would now be installed.
Because it is installed in the local project, you probably wouldn't be able to call that command directly, but you would put it on your `package.json` file.
@@ -87,12 +87,12 @@ It could look like this:
"description": "",
"main": "index.js",
"scripts": {
- "generate-client": "openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios --useOptions --useUnionTypes"
+ "generate-client": "openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios"
},
"author": "",
"license": "",
"devDependencies": {
- "openapi-typescript-codegen": "^0.20.1",
+ "@hey-api/openapi-ts": "^0.27.38",
"typescript": "^4.6.2"
}
}
@@ -106,7 +106,7 @@ After having that NPM `generate-client` script there, you can run it with:
$ npm run generate-client
frontend-app@1.0.0 generate-client /home/user/code/frontend-app
-> openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios --useOptions --useUnionTypes
+> openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios
```
@@ -254,12 +254,12 @@ Now as the end result is in a file `openapi.json`, you would modify the `package
"description": "",
"main": "index.js",
"scripts": {
- "generate-client": "openapi --input ./openapi.json --output ./src/client --client axios --useOptions --useUnionTypes"
+ "generate-client": "openapi-ts --input ./openapi.json --output ./src/client --client axios"
},
"author": "",
"license": "",
"devDependencies": {
- "openapi-typescript-codegen": "^0.20.1",
+ "@hey-api/openapi-ts": "^0.27.38",
"typescript": "^4.6.2"
}
}
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index 97889ab9f..5ae22dde3 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -7,10 +7,44 @@ hide:
## Latest Changes
+### Docs
+
+* 📝 Fix typo in `docs/es/docs/async.md`. PR [#11400](https://github.com/tiangolo/fastapi/pull/11400) by [@fabianfalon](https://github.com/fabianfalon).
+* 📝 Update OpenAPI client generation docs to use `@hey-api/openapi-ts`. PR [#11339](https://github.com/tiangolo/fastapi/pull/11339) by [@jordanshatford](https://github.com/jordanshatford).
+
+### Translations
+
+* 🌐 Add Russian translation for `docs/ru/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md`. PR [#11411](https://github.com/tiangolo/fastapi/pull/11411) by [@anton2yakovlev](https://github.com/anton2yakovlev).
+* 🌐 Add Portuguese translations for `learn/index.md` `resources/index.md` `help/index.md` `about/index.md`. PR [#10807](https://github.com/tiangolo/fastapi/pull/10807) by [@nazarepiedady](https://github.com/nazarepiedady).
+* 🌐 Update Russian translations for deployments docs. PR [#11271](https://github.com/tiangolo/fastapi/pull/11271) by [@Lufa1u](https://github.com/Lufa1u).
+* 🌐 Add Bengali translations for `docs/bn/docs/python-types.md`. PR [#11376](https://github.com/tiangolo/fastapi/pull/11376) by [@imtiaz101325](https://github.com/imtiaz101325).
+* 🌐 Add Korean translation for `docs/ko/docs/tutorial/security/simple-oauth2.md`. PR [#5744](https://github.com/tiangolo/fastapi/pull/5744) by [@KdHyeon0661](https://github.com/KdHyeon0661).
+* 🌐 Add Korean translation for `docs/ko/docs/help-fastapi.md`. PR [#4139](https://github.com/tiangolo/fastapi/pull/4139) by [@kty4119](https://github.com/kty4119).
+* 🌐 Add Korean translation for `docs/ko/docs/advanced/events.md`. PR [#5087](https://github.com/tiangolo/fastapi/pull/5087) by [@pers0n4](https://github.com/pers0n4).
+* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/path-operation-configuration.md`. PR [#1954](https://github.com/tiangolo/fastapi/pull/1954) by [@SwftAlpc](https://github.com/SwftAlpc).
+* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/request-forms-and-files.md`. PR [#1946](https://github.com/tiangolo/fastapi/pull/1946) by [@SwftAlpc](https://github.com/SwftAlpc).
+* 🌐 Add Russian translation for `docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md`. PR [#10532](https://github.com/tiangolo/fastapi/pull/10532) by [@AlertRED](https://github.com/AlertRED).
+* 🌐 Add Korean translation for `docs/ko/docs/tutorial/debugging.md`. PR [#5695](https://github.com/tiangolo/fastapi/pull/5695) by [@JungWooGeon](https://github.com/JungWooGeon).
+
+### Internal
+
+* ⬆️ Upgrade version of typer for docs. PR [#11393](https://github.com/tiangolo/fastapi/pull/11393) by [@tiangolo](https://github.com/tiangolo).
+
+## 0.110.1
+
+### Fixes
+
+* 🐛 Fix parameterless `Depends()` with generics. PR [#9479](https://github.com/tiangolo/fastapi/pull/9479) by [@nzig](https://github.com/nzig).
+
### Refactors
+* ♻️ Update mypy. PR [#11049](https://github.com/tiangolo/fastapi/pull/11049) by [@k0t3n](https://github.com/k0t3n).
* ♻️ Simplify string format with f-strings in `fastapi/applications.py`. PR [#11335](https://github.com/tiangolo/fastapi/pull/11335) by [@igeni](https://github.com/igeni).
+### Upgrades
+
+* ⬆️ Upgrade Starlette to >=0.37.2,<0.38.0, remove Starlette filterwarning for internal tests. PR [#11266](https://github.com/tiangolo/fastapi/pull/11266) by [@nothielf](https://github.com/nothielf).
+
### Docs
* 📝 Tweak docs and translations links and remove old docs translations. PR [#11381](https://github.com/tiangolo/fastapi/pull/11381) by [@tiangolo](https://github.com/tiangolo).
@@ -27,6 +61,7 @@ hide:
### Translations
+* 🌐 Add German translation for `docs/de/docs/tutorial/response-status-code.md`. PR [#10357](https://github.com/tiangolo/fastapi/pull/10357) by [@nilslindemann](https://github.com/nilslindemann).
* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/query-params.md`. PR [#3480](https://github.com/tiangolo/fastapi/pull/3480) by [@jaystone776](https://github.com/jaystone776).
* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/body.md`. PR [#3481](https://github.com/tiangolo/fastapi/pull/3481) by [@jaystone776](https://github.com/jaystone776).
* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/path-params.md`. PR [#3479](https://github.com/tiangolo/fastapi/pull/3479) by [@jaystone776](https://github.com/jaystone776).
@@ -162,6 +197,12 @@ hide:
### Internal
+* 👥 Update FastAPI People. PR [#11387](https://github.com/tiangolo/fastapi/pull/11387) by [@tiangolo](https://github.com/tiangolo).
+* ⬆ Bump actions/cache from 3 to 4. PR [#10988](https://github.com/tiangolo/fastapi/pull/10988) by [@dependabot[bot]](https://github.com/apps/dependabot).
+* ⬆ Bump pypa/gh-action-pypi-publish from 1.8.11 to 1.8.14. PR [#11318](https://github.com/tiangolo/fastapi/pull/11318) by [@dependabot[bot]](https://github.com/apps/dependabot).
+* ⬆ Bump pillow from 10.1.0 to 10.2.0. PR [#11011](https://github.com/tiangolo/fastapi/pull/11011) by [@dependabot[bot]](https://github.com/apps/dependabot).
+* ⬆ Bump black from 23.3.0 to 24.3.0. PR [#11325](https://github.com/tiangolo/fastapi/pull/11325) by [@dependabot[bot]](https://github.com/apps/dependabot).
+* 👷 Add cron to run test once a week on monday. PR [#11377](https://github.com/tiangolo/fastapi/pull/11377) by [@estebanx64](https://github.com/estebanx64).
* ➕ Replace mkdocs-markdownextradata-plugin with mkdocs-macros-plugin. PR [#11383](https://github.com/tiangolo/fastapi/pull/11383) by [@tiangolo](https://github.com/tiangolo).
* 👷 Disable MkDocs insiders social plugin while an issue in MkDocs Material is handled. PR [#11373](https://github.com/tiangolo/fastapi/pull/11373) by [@tiangolo](https://github.com/tiangolo).
* 👷 Fix logic for when to install and use MkDocs Insiders. PR [#11372](https://github.com/tiangolo/fastapi/pull/11372) by [@tiangolo](https://github.com/tiangolo).
diff --git a/docs/es/docs/async.md b/docs/es/docs/async.md
index 0fdc30739..dcd6154be 100644
--- a/docs/es/docs/async.md
+++ b/docs/es/docs/async.md
@@ -190,7 +190,7 @@ Luego, el cajero / cocinero 👨🍳 finalmente regresa con tus hamburguesas
@@ -315,7 +315,7 @@ $ docker run -d --name mycontainer -p 80:80 myimage
Вы можете проверить, что Ваш Docker-контейнер работает перейдя по ссылке:
http://192.168.99.100/items/5?q=somequery или
http://127.0.0.1/items/5?q=somequery (или похожей, которую использует Ваш Docker-хост).
-Там Вы увидите:
+Там вы увидите:
```JSON
{"item_id": 5, "q": "somequery"}
@@ -325,21 +325,21 @@ $ docker run -d --name mycontainer -p 80:80 myimage
Теперь перейдите по ссылке
http://192.168.99.100/docs или
http://127.0.0.1/docs (или похожей, которую использует Ваш Docker-хост).
-Здесь Вы увидите автоматическую интерактивную документацию API (предоставляемую
Swagger UI):
+Здесь вы увидите автоматическую интерактивную документацию API (предоставляемую
Swagger UI):

## Альтернативная документация API
-Также Вы можете перейти по ссылке
http://192.168.99.100/redoc or
http://127.0.0.1/redoc (или похожей, которую использует Ваш Docker-хост).
+Также вы можете перейти по ссылке
http://192.168.99.100/redoc or
http://127.0.0.1/redoc (или похожей, которую использует Ваш Docker-хост).
-Здесь Вы увидите альтернативную автоматическую документацию API (предоставляемую
ReDoc):
+Здесь вы увидите альтернативную автоматическую документацию API (предоставляемую
ReDoc):

## Создание Docker-образа на основе однофайлового приложения FastAPI
-Если Ваше приложение FastAPI помещено в один файл, например, `main.py` и структура Ваших файлов похожа на эту:
+Если ваше приложение FastAPI помещено в один файл, например, `main.py` и структура Ваших файлов похожа на эту:
```
.
@@ -376,7 +376,7 @@ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
Давайте вспомним о [Концепциях развёртывания](./concepts.md){.internal-link target=_blank} и применим их к контейнерам.
-Контейнеры - это, в основном, инструмент упрощающий **сборку и развёртывание** приложения и они не обязыают к применению какой-то определённой **концепции развёртывания**, а значит мы можем выбирать нужную стратегию.
+Контейнеры - это, в основном, инструмент упрощающий **сборку и развёртывание** приложения и они не обязывают к применению какой-то определённой **концепции развёртывания**, а значит мы можем выбирать нужную стратегию.
**Хорошая новость** в том, что независимо от выбранной стратегии, мы всё равно можем покрыть все концепции развёртывания. 🎉
@@ -412,7 +412,7 @@ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
## Запуск нескольких экземпляров приложения - Указание количества процессов
-Если у Вас есть
кластер машин под управлением **Kubernetes**, Docker Swarm Mode, Nomad или аналогичной сложной системой оркестрации контейнеров, скорее всего, вместо использования менеджера процессов (типа Gunicorn и его воркеры) в каждом контейнере, Вы захотите **управлять количеством запущенных экземпляров приложения** на **уровне кластера**.
+Если у вас есть
кластер машин под управлением **Kubernetes**, Docker Swarm Mode, Nomad или аналогичной сложной системой оркестрации контейнеров, скорее всего, вместо использования менеджера процессов (типа Gunicorn и его воркеры) в каждом контейнере, вы захотите **управлять количеством запущенных экземпляров приложения** на **уровне кластера**.
В любую из этих систем управления контейнерами обычно встроен способ управления **количеством запущенных контейнеров** для распределения **нагрузки** от входящих запросов на **уровне кластера**.
@@ -427,17 +427,17 @@ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
!!! tip "Подсказка"
**Прокси-сервер завершения работы TLS** одновременно может быть **балансировщиком нагрузки**.
-Система оркестрации, которую Вы используете для запуска и управления контейнерами, имеет встроенный инструмент **сетевого взаимодействия** (например, для передачи HTTP-запросов) между контейнерами с Вашими приложениями и **балансировщиком нагрузки** (который также может быть **прокси-сервером**).
+Система оркестрации, которую вы используете для запуска и управления контейнерами, имеет встроенный инструмент **сетевого взаимодействия** (например, для передачи HTTP-запросов) между контейнерами с Вашими приложениями и **балансировщиком нагрузки** (который также может быть **прокси-сервером**).
### Один балансировщик - Множество контейнеров
-При работе с **Kubernetes** или аналогичными системами оркестрации использование их внутреннней сети позволяет иметь один **балансировщик нагрузки**, который прослушивает **главный** порт и передаёт запросы **множеству запущенных контейнеров** с Вашими приложениями.
+При работе с **Kubernetes** или аналогичными системами оркестрации использование их внутренней сети позволяет иметь один **балансировщик нагрузки**, который прослушивает **главный** порт и передаёт запросы **множеству запущенных контейнеров** с Вашими приложениями.
В каждом из контейнеров обычно работает **только один процесс** (например, процесс Uvicorn управляющий Вашим приложением FastAPI). Контейнеры могут быть **идентичными**, запущенными на основе одного и того же образа, но у каждого будут свои отдельные процесс, память и т.п. Таким образом мы получаем преимущества **распараллеливания** работы по **разным ядрам** процессора или даже **разным машинам**.
Система управления контейнерами с **балансировщиком нагрузки** будет **распределять запросы** к контейнерам с приложениями **по очереди**. То есть каждый запрос будет обработан одним из множества **одинаковых контейнеров** с одним и тем же приложением.
-**Балансировщик нагрузки** может обрабатывать запросы к *разным* приложениям, расположенным в Вашем кластере (например, если у них разные домены или префиксы пути) и передавать запросы нужному контейнеру с требуемым приложением.
+**Балансировщик нагрузки** может обрабатывать запросы к *разным* приложениям, расположенным в вашем кластере (например, если у них разные домены или префиксы пути) и передавать запросы нужному контейнеру с требуемым приложением.
### Один процесс на контейнер
@@ -449,35 +449,35 @@ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
###
Множество процессов внутри контейнера для особых случаев
-Безусловно, бывают **особые случаи**, когда может понадобится внутри контейнера запускать **менеджер процессов Gunicorn**, управляющий несколькими **процессами Uvicorn**.
+Безусловно, бывают **особые случаи**, когда может понадобиться внутри контейнера запускать **менеджер процессов Gunicorn**, управляющий несколькими **процессами Uvicorn**.
-Для таких случаев Вы можете использовать **официальный Docker-образ** (прим. пер: - *здесь и далее на этой странице, если Вы встретите сочетание "официальный Docker-образ" без уточнений, то автор имеет в виду именно предоставляемый им образ*), где в качестве менеджера процессов используется **Gunicorn**, запускающий несколько **процессов Uvicorn** и некоторые настройки по умолчанию, автоматически устанавливающие количество запущенных процессов в зависимости от количества ядер Вашего процессора. Я расскажу Вам об этом подробнее тут: [Официальный Docker-образ со встроенными Gunicorn и Uvicorn](#docker-gunicorn-uvicorn).
+Для таких случаев вы можете использовать **официальный Docker-образ** (прим. пер: - *здесь и далее на этой странице, если вы встретите сочетание "официальный Docker-образ" без уточнений, то автор имеет в виду именно предоставляемый им образ*), где в качестве менеджера процессов используется **Gunicorn**, запускающий несколько **процессов Uvicorn** и некоторые настройки по умолчанию, автоматически устанавливающие количество запущенных процессов в зависимости от количества ядер вашего процессора. Я расскажу вам об этом подробнее тут: [Официальный Docker-образ со встроенными Gunicorn и Uvicorn](#docker-gunicorn-uvicorn).
Некоторые примеры подобных случаев:
#### Простое приложение
-Вы можете использовать менеджер процессов внутри контейнера, если Ваше приложение **настолько простое**, что у Вас нет необходимости (по крайней мере, пока нет) в тщательных настройках количества процессов и Вам достаточно имеющихся настроек по умолчанию (если используется официальный Docker-образ) для запуска приложения **только на одном сервере**, а не в кластере.
+Вы можете использовать менеджер процессов внутри контейнера, если ваше приложение **настолько простое**, что у вас нет необходимости (по крайней мере, пока нет) в тщательных настройках количества процессов и вам достаточно имеющихся настроек по умолчанию (если используется официальный Docker-образ) для запуска приложения **только на одном сервере**, а не в кластере.
#### Docker Compose
-С помощью **Docker Compose** можно разворачивать несколько контейнеров на **одном сервере** (не кластере), но при это у Вас не будет простого способа управления количеством запущенных контейнеров с одновременным сохранением общей сети и **балансировки нагрузки**.
+С помощью **Docker Compose** можно разворачивать несколько контейнеров на **одном сервере** (не кластере), но при это у вас не будет простого способа управления количеством запущенных контейнеров с одновременным сохранением общей сети и **балансировки нагрузки**.
В этом случае можно использовать **менеджер процессов**, управляющий **несколькими процессами**, внутри **одного контейнера**.
#### Prometheus и прочие причины
-У Вас могут быть и **другие причины**, когда использование **множества процессов** внутри **одного контейнера** будет проще, нежели запуск **нескольких контейнеров** с **единственным процессом** в каждом из них.
+У вас могут быть и **другие причины**, когда использование **множества процессов** внутри **одного контейнера** будет проще, нежели запуск **нескольких контейнеров** с **единственным процессом** в каждом из них.
-Например (в зависимости от конфигурации), у Вас могут быть инструменты подобные экспортёру Prometheus, которые должны иметь доступ к **каждому запросу** приходящему в контейнер.
+Например (в зависимости от конфигурации), у вас могут быть инструменты подобные экспортёру Prometheus, которые должны иметь доступ к **каждому запросу** приходящему в контейнер.
-Если у Вас будет **несколько контейнеров**, то Prometheus, по умолчанию, **при сборе метрик** получит их **только с одного контейнера**, который обрабатывает конкретный запрос, вместо **сбора метрик** со всех работающих контейнеров.
+Если у вас будет **несколько контейнеров**, то Prometheus, по умолчанию, **при сборе метрик** получит их **только с одного контейнера**, который обрабатывает конкретный запрос, вместо **сбора метрик** со всех работающих контейнеров.
В таком случае может быть проще иметь **один контейнер** со **множеством процессов**, с нужным инструментом (таким как экспортёр Prometheus) в этом же контейнере и собирающем метрики со всех внутренних процессов этого контейнера.
---
-Самое главное - **ни одно** из перечисленных правил не является **высеченным в камне** и Вы не обязаны слепо их повторять. Вы можете использовать эти идеи при **рассмотрении Вашего конкретного случая** и самостоятельно решать, какая из концепции подходит лучше:
+Самое главное - **ни одно** из перечисленных правил не является **высеченным на камне** и вы не обязаны слепо их повторять. вы можете использовать эти идеи при **рассмотрении вашего конкретного случая** и самостоятельно решать, какая из концепции подходит лучше:
* Использование более безопасного протокола HTTPS
* Настройки запуска приложения
@@ -488,41 +488,41 @@ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
## Управление памятью
-При **запуске одного процесса на контейнер** Вы получаете относительно понятный, стабильный и ограниченный объём памяти, потребляемый одним контейнером.
+При **запуске одного процесса на контейнер** вы получаете относительно понятный, стабильный и ограниченный объём памяти, потребляемый одним контейнером.
Вы можете установить аналогичные ограничения по памяти при конфигурировании своей системы управления контейнерами (например, **Kubernetes**). Таким образом система сможет **изменять количество контейнеров** на **доступных ей машинах** приводя в соответствие количество памяти нужной контейнерам с количеством памяти доступной в кластере (наборе доступных машин).
-Если у Вас **простенькое** приложение, вероятно у Вас не будет **необходимости** устанавливать жёсткие ограничения на выделяемую ему память. Но если приложение **использует много памяти** (например, оно использует модели **машинного обучения**), Вам следует проверить, как много памяти ему требуется и отрегулировать **количество контейнеров** запущенных на **каждой машине** (может быть даже добавить машин в кластер).
+Если у вас **простенькое** приложение, вероятно у вас не будет **необходимости** устанавливать жёсткие ограничения на выделяемую ему память. Но если приложение **использует много памяти** (например, оно использует модели **машинного обучения**), вам следует проверить, как много памяти ему требуется и отрегулировать **количество контейнеров** запущенных на **каждой машине** (может быть даже добавить машин в кластер).
-Если Вы запускаете **несколько процессов в контейнере**, то должны быть уверены, что эти процессы не **займут памяти больше**, чем доступно для контейнера.
+Если вы запускаете **несколько процессов в контейнере**, то должны быть уверены, что эти процессы не **займут памяти больше**, чем доступно для контейнера.
## Подготовительные шаги при запуске контейнеров
-Есть два основных подхода, которые Вы можете использовать при запуске контейнеров (Docker, Kubernetes и т.п.).
+Есть два основных подхода, которые вы можете использовать при запуске контейнеров (Docker, Kubernetes и т.п.).
### Множество контейнеров
-Когда Вы запускаете **множество контейнеров**, в каждом из которых работает **только один процесс** (например, в кластере **Kubernetes**), может возникнуть необходимость иметь **отдельный контейнер**, который осуществит **предварительные шаги перед запуском** остальных контейнеров (например, применяет миграции к базе данных).
+Когда вы запускаете **множество контейнеров**, в каждом из которых работает **только один процесс** (например, в кластере **Kubernetes**), может возникнуть необходимость иметь **отдельный контейнер**, который осуществит **предварительные шаги перед запуском** остальных контейнеров (например, применяет миграции к базе данных).
!!! info "Информация"
При использовании Kubernetes, это может быть
Инициализирующий контейнер.
-При отсутствии такой необходимости (допустим, не нужно применять миграции к базе данных, а только проверить, что она готова принимать соединения), Вы можете проводить такую проверку в каждом контейнере перед запуском его основного процесса и запускать все контейнеры **одновременно**.
+При отсутствии такой необходимости (допустим, не нужно применять миграции к базе данных, а только проверить, что она готова принимать соединения), вы можете проводить такую проверку в каждом контейнере перед запуском его основного процесса и запускать все контейнеры **одновременно**.
### Только один контейнер
-Если у Вас несложное приложение для работы которого достаточно **одного контейнера**, но в котором работает **несколько процессов** (или один процесс), то прохождение предварительных шагов можно осуществить в этом же контейнере до запуска основного процесса. Официальный Docker-образ поддерживает такие действия.
+Если у вас несложное приложение для работы которого достаточно **одного контейнера**, но в котором работает **несколько процессов** (или один процесс), то прохождение предварительных шагов можно осуществить в этом же контейнере до запуска основного процесса. Официальный Docker-образ поддерживает такие действия.
## Официальный Docker-образ с Gunicorn и Uvicorn
-Я подготовил для Вас Docker-образ, в который включён Gunicorn управляющий процессами (воркерами) Uvicorn, в соответствии с концепциями рассмотренными в предыдущей главе: [Рабочие процессы сервера (воркеры) - Gunicorn совместно с Uvicorn](./server-workers.md){.internal-link target=_blank}.
+Я подготовил для вас Docker-образ, в который включён Gunicorn управляющий процессами (воркерами) Uvicorn, в соответствии с концепциями рассмотренными в предыдущей главе: [Рабочие процессы сервера (воркеры) - Gunicorn совместно с Uvicorn](./server-workers.md){.internal-link target=_blank}.
Этот образ может быть полезен для ситуаций описанных тут: [Множество процессов внутри контейнера для особых случаев](#special-cases).
*
tiangolo/uvicorn-gunicorn-fastapi.
!!! warning "Предупреждение"
- Скорее всего у Вас **нет необходимости** в использовании этого образа или подобного ему и лучше создать свой образ с нуля как описано тут: [Создать Docker-образ для FastAPI](#docker-fastapi).
+ Скорее всего у вас **нет необходимости** в использовании этого образа или подобного ему и лучше создать свой образ с нуля как описано тут: [Создать Docker-образ для FastAPI](#docker-fastapi).
В этом образе есть **автоматический** механизм подстройки для запуска **необходимого количества процессов** в соответствии с доступным количеством ядер процессора.
@@ -539,11 +539,11 @@ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
Это означает, что он будет пытаться **выжать** из процессора как можно больше **производительности**.
-Но Вы можете изменять и обновлять конфигурацию с помощью **переменных окружения** и т.п.
+Но вы можете изменять и обновлять конфигурацию с помощью **переменных окружения** и т.п.
Поскольку количество процессов зависит от процессора, на котором работает контейнер, **объём потребляемой памяти** также будет зависеть от этого.
-А значит, если Вашему приложению требуется много оперативной памяти (например, оно использует модели машинного обучения) и Ваш сервер имеет центральный процессор с большим количеством ядер, но **не слишком большим объёмом оперативной памяти**, то может дойти до того, что контейнер попытается занять памяти больше, чем доступно, из-за чего будет падение производительности (или сервер вовсе упадёт). 🚨
+А значит, если вашему приложению требуется много оперативной памяти (например, оно использует модели машинного обучения) и Ваш сервер имеет центральный процессор с большим количеством ядер, но **не слишком большим объёмом оперативной памяти**, то может дойти до того, что контейнер попытается занять памяти больше, чем доступно, из-за чего будет падение производительности (или сервер вовсе упадёт). 🚨
### Написание `Dockerfile`
@@ -562,7 +562,7 @@ COPY ./app /app
### Большие приложения
-Если Вы успели ознакомиться с разделом [Приложения содержащие много файлов](../tutorial/bigger-applications.md){.internal-link target=_blank}, состоящие из множества файлов, Ваш Dockerfile может выглядеть так:
+Если вы успели ознакомиться с разделом [Приложения содержащие много файлов](../tutorial/bigger-applications.md){.internal-link target=_blank}, состоящие из множества файлов, Ваш Dockerfile может выглядеть так:
```Dockerfile hl_lines="7"
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9
@@ -576,9 +576,9 @@ COPY ./app /app/app
### Как им пользоваться
-Если Вы используете **Kubernetes** (или что-то вроде того), скорее всего Вам **не нужно** использовать официальный Docker-образ (или другой похожий) в качестве основы, так как управление **количеством запущенных контейнеров** должно быть настроено на уровне кластера. В таком случае лучше **создать образ с нуля**, как описано в разделе Создать [Docker-образ для FastAPI](#docker-fastapi).
+Если вы используете **Kubernetes** (или что-то вроде того), скорее всего вам **не нужно** использовать официальный Docker-образ (или другой похожий) в качестве основы, так как управление **количеством запущенных контейнеров** должно быть настроено на уровне кластера. В таком случае лучше **создать образ с нуля**, как описано в разделе Создать [Docker-образ для FastAPI](#docker-fastapi).
-Официальный образ может быть полезен в отдельных случаях, описанных выше в разделе [Множество процессов внутри контейнера для особых случаев](#special-cases). Например, если Ваше приложение **достаточно простое**, не требует запуска в кластере и способно уместиться в один контейнер, то его настройки по умолчанию будут работать довольно хорошо. Или же Вы развертываете его с помощью **Docker Compose**, работаете на одном сервере и т. д
+Официальный образ может быть полезен в отдельных случаях, описанных выше в разделе [Множество процессов внутри контейнера для особых случаев](#special-cases). Например, если ваше приложение **достаточно простое**, не требует запуска в кластере и способно уместиться в один контейнер, то его настройки по умолчанию будут работать довольно хорошо. Или же вы развертываете его с помощью **Docker Compose**, работаете на одном сервере и т. д
## Развёртывание образа контейнера
@@ -590,11 +590,11 @@ COPY ./app /app/app
* С использованием **Kubernetes** в кластере
* С использованием режима Docker Swarm в кластере
* С использованием других инструментов, таких как Nomad
-* С использованием облачного сервиса, который будет управлять разворачиванием Вашего контейнера
+* С использованием облачного сервиса, который будет управлять разворачиванием вашего контейнера
## Docker-образ и Poetry
-Если Вы пользуетесь
Poetry для управления зависимостями Вашего проекта, то можете использовать многоэтапную сборку образа:
+Если вы пользуетесь
Poetry для управления зависимостями вашего проекта, то можете использовать многоэтапную сборку образа:
```{ .dockerfile .annotate }
# (1)
@@ -664,19 +664,19 @@ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
**Этапы сборки Docker-образа** являются частью `Dockerfile` и работают как **временные образы контейнеров**. Они нужны только для создания файлов, используемых в дальнейших этапах.
-Первый этап был нужен только для **установки Poetry** и **создания файла `requirements.txt`**, в которым прописаны зависимости Вашего проекта, взятые из файла `pyproject.toml`.
+Первый этап был нужен только для **установки Poetry** и **создания файла `requirements.txt`**, в которым прописаны зависимости вашего проекта, взятые из файла `pyproject.toml`.
На **следующем этапе** `pip` будет использовать файл `requirements.txt`.
В итоговом образе будет содержаться **только последний этап сборки**, предыдущие этапы будут отброшены.
-При использовании Poetry, имеет смысл использовать **многоэтапную сборку Docker-образа**, потому что на самом деле Вам не нужен Poetry и его зависимости в окончательном образе контейнера, Вам **нужен только** сгенерированный файл `requirements.txt` для установки зависимостей Вашего проекта.
+При использовании Poetry, имеет смысл использовать **многоэтапную сборку Docker-образа**, потому что на самом деле вам не нужен Poetry и его зависимости в окончательном образе контейнера, вам **нужен только** сгенерированный файл `requirements.txt` для установки зависимостей вашего проекта.
А на последнем этапе, придерживаясь описанных ранее правил, создаётся итоговый образ
### Использование прокси-сервера завершения TLS и Poetry
-И снова повторюсь, если используете прокси-сервер (балансировщик нагрузки), такой, как Nginx или Traefik, добавьте в команду запуска опцию `--proxy-headers`:
+И снова повторюсь, если используете прокси-сервер (балансировщик нагрузки), такой как Nginx или Traefik, добавьте в команду запуска опцию `--proxy-headers`:
```Dockerfile
CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"]
@@ -695,6 +695,6 @@ CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port"
В большинстве случаев Вам, вероятно, не нужно использовать какой-либо базовый образ, **лучше создать образ контейнера с нуля** на основе официального Docker-образа Python.
-Позаботившись о **порядке написания** инструкций в `Dockerfile`, Вы сможете использовать **кэш Docker'а**, **минимизировав время сборки**, максимально повысив свою производительность (и избежать скуки). 😎
+Позаботившись о **порядке написания** инструкций в `Dockerfile`, вы сможете использовать **кэш Docker'а**, **минимизировав время сборки**, максимально повысив свою производительность (и не заскучать). 😎
В некоторых особых случаях вы можете использовать официальный образ Docker для FastAPI. 🤓
diff --git a/docs/ru/docs/deployment/https.md b/docs/ru/docs/deployment/https.md
index a53ab6927..5aa300331 100644
--- a/docs/ru/docs/deployment/https.md
+++ b/docs/ru/docs/deployment/https.md
@@ -1,11 +1,11 @@
# Об HTTPS
-Обычно представляется, что HTTPS это некая опция, которая либо "включена", либо нет.
+Обычно представляется, что HTTPS это некая опция, которая либо "включена", либо нет.
Но всё несколько сложнее.
!!! tip "Заметка"
- Если Вы торопитесь или Вам не интересно, можете перейти на следующую страницу этого пошагового руководства по размещению приложений на серверах с использованием различных технологий.
+ Если вы торопитесь или вам не интересно, можете перейти на следующую страницу этого пошагового руководства по размещению приложений на серверах с использованием различных технологий.
Чтобы **изучить основы HTTPS** для клиента, перейдите по ссылке
https://howhttps.works/.
@@ -22,8 +22,8 @@
* **TCP не знает о "доменах"**, но знает об IP-адресах.
* Информация о **запрашиваемом домене** извлекается из запроса **на уровне HTTP**.
* **Сертификаты HTTPS** "сертифицируют" **конкретный домен**, но проверка сертификатов и шифрование данных происходит на уровне протокола TCP, то есть **до того**, как станет известен домен-получатель данных.
-* **По умолчанию** это означает, что у Вас может быть **только один сертификат HTTPS на один IP-адрес**.
- * Не важно, насколько большой у Вас сервер и насколько маленькие приложения на нём могут быть.
+* **По умолчанию** это означает, что у вас может быть **только один сертификат HTTPS на один IP-адрес**.
+ * Не важно, насколько большой у вас сервер и насколько маленькие приложения на нём могут быть.
* Однако, у этой проблемы есть **решение**.
* Существует **расширение** протокола **TLS** (который работает на уровне TCP, то есть до HTTP) называемое **
SNI**.
* Расширение SNI позволяет одному серверу (с **одним IP-адресом**) иметь **несколько сертификатов HTTPS** и обслуживать **множество HTTPS-доменов/приложений**.
@@ -35,12 +35,12 @@
* получение **зашифрованных HTTPS-запросов**
* отправка **расшифрованных HTTP запросов** в соответствующее HTTP-приложение, работающее на том же сервере (в нашем случае, это приложение **FastAPI**)
-* получние **HTTP-ответа** от приложения
+* получение **HTTP-ответа** от приложения
* **шифрование ответа** используя подходящий **сертификат HTTPS**
* отправка зашифрованного **HTTPS-ответа клиенту**.
Такой сервер часто называют **
Прокси-сервер завершения работы TLS** или просто "прокси-сервер".
-Вот некоторые варианты, которые Вы можете использовать в качестве такого прокси-сервера:
+Вот некоторые варианты, которые вы можете использовать в качестве такого прокси-сервера:
* Traefik (может обновлять сертификаты)
* Caddy (может обновлять сертификаты)
@@ -67,11 +67,11 @@
### Имя домена
-Чаще всего, всё начинается с **приобретения имени домена**. Затем нужно настроить DNS-сервер (вероятно у того же провайдера, который выдал Вам домен).
+Чаще всего, всё начинается с **приобретения имени домена**. Затем нужно настроить DNS-сервер (вероятно у того же провайдера, который выдал вам домен).
-Далее, возможно, Вы получаете "облачный" сервер (виртуальную машину) или что-то типа этого, у которого есть
постоянный **публичный IP-адрес**.
+Далее, возможно, вы получаете "облачный" сервер (виртуальную машину) или что-то типа этого, у которого есть
постоянный **публичный IP-адрес**.
-На DNS-сервере (серверах) Вам следует настроить соответствующую ресурсную запись ("`запись A`"), указав, что **Ваш домен** связан с публичным **IP-адресом Вашего сервера**.
+На DNS-сервере (серверах) вам следует настроить соответствующую ресурсную запись ("`запись A`"), указав, что **Ваш домен** связан с публичным **IP-адресом вашего сервера**.
Обычно эту запись достаточно указать один раз, при первоначальной настройке всего сервера.
@@ -82,9 +82,9 @@
Теперь давайте сфокусируемся на работе с HTTPS.
-Всё начинается с того, что браузер спрашивает у **DNS-серверов**, какой **IP-адрес связан с доменом**, для примера возьмём домен `someapp.example.com`.
+Всё начинается с того, что браузер спрашивает у **DNS-серверов**, какой **IP-адрес связан с доменом**, для примера возьмём домен `someapp.example.com`.
-DNS-сервера присылают браузеру определённый **IP-адрес**, тот самый публичный IP-адрес Вашего сервера, который Вы указали в ресурсной "записи А" при настройке.
+DNS-сервера присылают браузеру определённый **IP-адрес**, тот самый публичный IP-адрес вашего сервера, который вы указали в ресурсной "записи А" при настройке.

@@ -96,7 +96,7 @@ DNS-сервера присылают браузеру определённый

-Эта часть клиент-серверного взаимодействия устанавливает TLS-соединение и называется **TLS-рукопожатием**.
+Эта часть клиент-серверного взаимодействия устанавливает TLS-соединение и называется **TLS-рукопожатием**.
### TLS с расширением SNI
@@ -185,7 +185,7 @@ DNS-сервера присылают браузеру определённый
* **Запуск в качестве программы-сервера** (как минимум, на время обновления сертификатов) на публичном IP-адресе домена.
* Как уже не раз упоминалось, только один процесс может прослушивать определённый порт определённого IP-адреса.
* Это одна из причин использования прокси-сервера ещё и в качестве программы обновления сертификатов.
- * В случае, если обновлением сертификатов занимается другая программа, Вам понадобится остановить прокси-сервер, запустить программу обновления сертификатов на сокете, предназначенном для прокси-сервера, настроить прокси-сервер на работу с новыми сертификатами и перезапустить его. Эта схема далека от идеальной, так как Ваши приложения будут недоступны на время отключения прокси-сервера.
+ * В случае, если обновлением сертификатов занимается другая программа, вам понадобится остановить прокси-сервер, запустить программу обновления сертификатов на сокете, предназначенном для прокси-сервера, настроить прокси-сервер на работу с новыми сертификатами и перезапустить его. Эта схема далека от идеальной, так как Ваши приложения будут недоступны на время отключения прокси-сервера.
Весь этот процесс обновления, одновременный с обслуживанием запросов, является одной из основных причин, по которой желательно иметь **отдельную систему для работы с HTTPS** в виде прокси-сервера завершения TLS, а не просто использовать сертификаты TLS непосредственно с сервером приложений (например, Uvicorn).
@@ -193,6 +193,6 @@ DNS-сервера присылают браузеру определённый
Наличие **HTTPS** очень важно и довольно **критично** в большинстве случаев. Однако, Вам, как разработчику, не нужно тратить много сил на это, достаточно **понимать эти концепции** и принципы их работы.
-Но узнав базовые основы **HTTPS** Вы можете легко совмещать разные инструменты, которые помогут Вам в дальнейшей разработке.
+Но узнав базовые основы **HTTPS** вы можете легко совмещать разные инструменты, которые помогут вам в дальнейшей разработке.
-В следующих главах я покажу Вам несколько примеров, как настраивать **HTTPS** для приложений **FastAPI**. 🔒
+В следующих главах я покажу вам несколько примеров, как настраивать **HTTPS** для приложений **FastAPI**. 🔒
diff --git a/docs/ru/docs/deployment/index.md b/docs/ru/docs/deployment/index.md
index d214a9d62..e88ddc3e2 100644
--- a/docs/ru/docs/deployment/index.md
+++ b/docs/ru/docs/deployment/index.md
@@ -8,7 +8,7 @@
Обычно **веб-приложения** размещают на удалённом компьютере с серверной программой, которая обеспечивает хорошую производительность, стабильность и т. д., Чтобы ваши пользователи могли эффективно, беспрерывно и беспроблемно обращаться к приложению.
-Это отличется от **разработки**, когда вы постоянно меняете код, делаете в нём намеренные ошибки и исправляете их, останавливаете и перезапускаете сервер разработки и т. д.
+Это отличается от **разработки**, когда вы постоянно меняете код, делаете в нём намеренные ошибки и исправляете их, останавливаете и перезапускаете сервер разработки и т. д.
## Стратегии развёртывания
diff --git a/docs/ru/docs/deployment/manually.md b/docs/ru/docs/deployment/manually.md
index 1d00b3086..a24580489 100644
--- a/docs/ru/docs/deployment/manually.md
+++ b/docs/ru/docs/deployment/manually.md
@@ -1,6 +1,6 @@
# Запуск сервера вручную - Uvicorn
-Для запуска приложения **FastAPI** на удалённой серверной машине Вам необходим программный сервер, поддерживающий протокол ASGI, такой как **Uvicorn**.
+Для запуска приложения **FastAPI** на удалённой серверной машине вам необходим программный сервер, поддерживающий протокол ASGI, такой как **Uvicorn**.
Существует три наиболее распространённые альтернативы:
@@ -10,16 +10,16 @@
## Сервер как машина и сервер как программа
-В этих терминах есть некоторые различия и Вам следует запомнить их. 💡
+В этих терминах есть некоторые различия и вам следует запомнить их. 💡
Слово "**сервер**" чаще всего используется в двух контекстах:
- удалённый или расположенный в "облаке" компьютер (физическая или виртуальная машина).
- программа, запущенная на таком компьютере (например, Uvicorn).
-Просто запомните, если Вам встретился термин "сервер", то обычно он подразумевает что-то из этих двух смыслов.
+Просто запомните, если вам встретился термин "сервер", то обычно он подразумевает что-то из этих двух смыслов.
-Когда имеют в виду именно удалённый компьютер, часто говорят просто **сервер**, но ещё его называют **машина**, **ВМ** (виртуальная машина), **нода**. Все эти термины обозначают одно и то же - удалённый компьютер, обычно под управлением Linux, на котором Вы запускаете программы.
+Когда имеют в виду именно удалённый компьютер, часто говорят просто **сервер**, но ещё его называют **машина**, **ВМ** (виртуальная машина), **нода**. Все эти термины обозначают одно и то же - удалённый компьютер, обычно под управлением Linux, на котором вы запускаете программы.
## Установка программного сервера
@@ -27,7 +27,7 @@
=== "Uvicorn"
- *
Uvicorn, молниесный ASGI сервер, основанный на библиотеках uvloop и httptools.
+ *
Uvicorn, очень быстрый ASGI сервер, основанный на библиотеках uvloop и httptools.
@@ -40,7 +40,7 @@
!!! tip "Подсказка"
- С опцией `standard`, Uvicorn будет установливаться и использоваться с некоторыми дополнительными рекомендованными зависимостями.
+ С опцией `standard`, Uvicorn будет устанавливаться и использоваться с некоторыми дополнительными рекомендованными зависимостями.
В них входит `uvloop`, высокопроизводительная замена `asyncio`, которая значительно ускоряет работу асинхронных программ.
@@ -62,7 +62,7 @@
## Запуск серверной программы
-Затем запустите Ваше приложение так же, как было указано в руководстве ранее, но без опции `--reload`:
+Затем запустите ваше приложение так же, как было указано в руководстве ранее, но без опции `--reload`:
=== "Uvicorn"
@@ -103,11 +103,11 @@ Starlette и **FastAPI** основаны на
`uvloop`, высокопроизводительной заменой `asyncio`.
-Но если Вы хотите использовать **Trio** напрямую, то можете воспользоваться **Hypercorn**, так как они совместимы. ✨
+Но если вы хотите использовать **Trio** напрямую, то можете воспользоваться **Hypercorn**, так как они совместимы. ✨
### Установка Hypercorn с Trio
-Для начала, Вам нужно установить Hypercorn с поддержкой Trio:
+Для начала, вам нужно установить Hypercorn с поддержкой Trio:
@@ -130,15 +130,15 @@ $ hypercorn main:app --worker-class trio
-Hypercorn, в свою очередь, запустит Ваше приложение использующее Trio.
+Hypercorn, в свою очередь, запустит ваше приложение использующее Trio.
-Таким образом, Вы сможете использовать Trio в своём приложении. Но лучше использовать AnyIO, для сохранения совместимости и с Trio, и с asyncio. 🎉
+Таким образом, вы сможете использовать Trio в своём приложении. Но лучше использовать AnyIO, для сохранения совместимости и с Trio, и с asyncio. 🎉
## Концепции развёртывания
В вышеприведённых примерах серверные программы (например Uvicorn) запускали только **один процесс**, принимающий входящие запросы с любого IP (на это указывал аргумент `0.0.0.0`) на определённый порт (в примерах мы указывали порт `80`).
-Это основная идея. Но возможно, Вы озаботитесь добавлением дополнительных возможностей, таких как:
+Это основная идея. Но возможно, вы озаботитесь добавлением дополнительных возможностей, таких как:
* Использование более безопасного протокола HTTPS
* Настройки запуска приложения
@@ -147,4 +147,4 @@ Hypercorn, в свою очередь, запустит Ваше приложе
* Управление памятью
* Использование перечисленных функций перед запуском приложения.
-Я поведаю Вам больше о каждой из этих концепций в следующих главах, с конкретными примерами стратегий работы с ними. 🚀
+Я расскажу вам больше о каждой из этих концепций в следующих главах, с конкретными примерами стратегий работы с ними. 🚀
diff --git a/docs/ru/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md b/docs/ru/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
new file mode 100644
index 000000000..2bd096189
--- /dev/null
+++ b/docs/ru/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
@@ -0,0 +1,139 @@
+# Зависимости в декораторах операции пути
+
+В некоторых случаях, возвращаемое значение зависимости не используется внутри *функции операции пути*.
+
+Или же зависимость не возвращает никакого значения.
+
+Но вам всё-таки нужно, чтобы она выполнилась.
+
+Для таких ситуаций, вместо объявления *функции операции пути* с параметром `Depends`, вы можете добавить список зависимостей `dependencies` в *декоратор операции пути*.
+
+## Добавление `dependencies` в *декоратор операции пути*
+
+*Декоратор операции пути* получает необязательный аргумент `dependencies`.
+
+Это должен быть `list` состоящий из `Depends()`:
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="19"
+ {!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
+ ```
+
+=== "Python 3.8+"
+
+ ```Python hl_lines="18"
+ {!> ../../../docs_src/dependencies/tutorial006_an.py!}
+ ```
+
+=== "Python 3.8 без Annotated"
+
+ !!! Подсказка
+ Рекомендуется использовать версию с Annotated, если возможно.
+
+ ```Python hl_lines="17"
+ {!> ../../../docs_src/dependencies/tutorial006.py!}
+ ```
+
+Зависимости из dependencies выполнятся так же, как и обычные зависимости. Но их значения (если они были) не будут переданы в *функцию операции пути*.
+
+!!! Подсказка
+ Некоторые редакторы кода определяют неиспользуемые параметры функций и подсвечивают их как ошибку.
+
+ Использование `dependencies` в *декораторе операции пути* гарантирует выполнение зависимостей, избегая при этом предупреждений редактора кода и других инструментов.
+
+ Это также должно помочь предотвратить путаницу у начинающих разработчиков, которые видят неиспользуемые параметры в коде и могут подумать что в них нет необходимости.
+
+!!! Дополнительная информация
+ В этом примере мы используем выдуманные пользовательские заголовки `X-Key` и `X-Token`.
+
+ Но в реальных проектах, при внедрении системы безопасности, вы получите больше пользы используя интегрированные [средства защиты (следующая глава)](../security/index.md){.internal-link target=_blank}.
+
+## Исключения в dependencies и возвращаемые значения
+
+Вы можете использовать те же *функции* зависимостей, что и обычно.
+
+### Требования к зависимостям
+
+Они могут объявлять требования к запросу (например заголовки) или другие подзависимости:
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="8 13"
+ {!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
+ ```
+
+=== "Python 3.8+"
+
+ ```Python hl_lines="7 12"
+ {!> ../../../docs_src/dependencies/tutorial006_an.py!}
+ ```
+
+=== "Python 3.8 без Annotated"
+
+ !!! Подсказка
+ Рекомендуется использовать версию с Annotated, если возможно.
+
+ ```Python hl_lines="6 11"
+ {!> ../../../docs_src/dependencies/tutorial006.py!}
+ ```
+
+### Вызов исключений
+
+Зависимости из dependencies могут вызывать исключения с помощью `raise`, как и обычные зависимости:
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="10 15"
+ {!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
+ ```
+
+=== "Python 3.8+"
+
+ ```Python hl_lines="9 14"
+ {!> ../../../docs_src/dependencies/tutorial006_an.py!}
+ ```
+
+=== "Python 3.8 без Annotated"
+
+ !!! Подсказка
+ Рекомендуется использовать версию с Annotated, если возможно.
+
+ ```Python hl_lines="8 13"
+ {!> ../../../docs_src/dependencies/tutorial006.py!}
+ ```
+
+### Возвращаемые значения
+
+И они могут возвращать значения или нет, эти значения использоваться не будут.
+
+Таким образом, вы можете переиспользовать обычную зависимость (возвращающую значение), которую вы уже используете где-то в другом месте, и хотя значение не будет использоваться, зависимость будет выполнена:
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="11 16"
+ {!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
+ ```
+
+=== "Python 3.8+"
+
+ ```Python hl_lines="10 15"
+ {!> ../../../docs_src/dependencies/tutorial006_an.py!}
+ ```
+
+=== "Python 3.8 без Annotated"
+
+ !!! Подсказка
+ Рекомендуется использовать версию с Annotated, если возможно.
+
+ ```Python hl_lines="9 14"
+ {!> ../../../docs_src/dependencies/tutorial006.py!}
+ ```
+
+## Dependencies для группы *операций путей*
+
+Позже, читая о том как структурировать большие приложения ([Bigger Applications - Multiple Files](../../tutorial/bigger-applications.md){.internal-link target=_blank}), возможно, многофайловые, вы узнаете как объявить единый параметр `dependencies` для всей группы *операций путей*.
+
+## Глобальный Dependencies
+
+Далее мы увидим, как можно добавить dependencies для всего `FastAPI` приложения, так чтобы они применялись к каждой *операции пути*.
diff --git a/docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md b/docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md
new file mode 100644
index 000000000..cd524cf66
--- /dev/null
+++ b/docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md
@@ -0,0 +1,275 @@
+# Зависимости с yield
+
+FastAPI поддерживает зависимости, которые выполняют некоторые
дополнительные действия после завершения работы.
+
+Для этого используйте `yield` вместо `return`, а дополнительный код напишите после него.
+
+!!! tip "Подсказка"
+ Обязательно используйте `yield` один-единственный раз.
+
+!!! note "Технические детали"
+ Любая функция, с которой может работать:
+
+ *
`@contextlib.contextmanager` или
+ *
`@contextlib.asynccontextmanager`
+
+ будет корректно использоваться в качестве **FastAPI**-зависимости.
+
+ На самом деле, FastAPI использует эту пару декораторов "под капотом".
+
+## Зависимость базы данных с помощью `yield`
+
+Например, с его помощью можно создать сессию работы с базой данных и закрыть его после завершения.
+
+Перед созданием ответа будет выполнен только код до и включая `yield`.
+
+```Python hl_lines="2-4"
+{!../../../docs_src/dependencies/tutorial007.py!}
+```
+
+Полученное значение и есть то, что будет внедрено в функцию операции пути и другие зависимости:
+
+```Python hl_lines="4"
+{!../../../docs_src/dependencies/tutorial007.py!}
+```
+
+Код, следующий за оператором `yield`, выполняется после доставки ответа:
+
+```Python hl_lines="5-6"
+{!../../../docs_src/dependencies/tutorial007.py!}
+```
+
+!!! tip "Подсказка"
+ Можно использовать как `async` так и обычные функции.
+
+ **FastAPI** это корректно обработает, и в обоих случаях будет делать то же самое, что и с обычными зависимостями.
+
+## Зависимость с `yield` и `try` одновременно
+
+Если использовать блок `try` в зависимости с `yield`, то будет получено всякое исключение, которое было выброшено при использовании зависимости.
+
+Например, если какой-то код в какой-то момент в середине, в другой зависимости или в *функции операции пути*, сделал "откат" транзакции базы данных или создал любую другую ошибку, то вы получите исключение в своей зависимости.
+
+Таким образом, можно искать конкретное исключение внутри зависимости с помощью `except SomeException`.
+
+Таким же образом можно использовать `finally`, чтобы убедиться, что обязательные шаги при выходе выполнены, независимо от того, было ли исключение или нет.
+
+```Python hl_lines="3 5"
+{!../../../docs_src/dependencies/tutorial007.py!}
+```
+
+## Подзависимости с `yield`
+
+Вы можете иметь подзависимости и "деревья" подзависимостей любого размера и формы, и любая из них или все они могут использовать `yield`.
+
+**FastAPI** будет следить за тем, чтобы "код по выходу" в каждой зависимости с `yield` выполнялся в правильном порядке.
+
+Например, `dependency_c` может иметь зависимость от `dependency_b`, а `dependency_b` от `dependency_a`:
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="6 14 22"
+ {!> ../../../docs_src/dependencies/tutorial008_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="5 13 21"
+ {!> ../../../docs_src/dependencies/tutorial008_an.py!}
+ ```
+
+=== "Python 3.6+ без Annotated"
+
+ !!! tip "Подсказка"
+ Предпочтительнее использовать версию с аннотацией, если это возможно.
+
+ ```Python hl_lines="4 12 20"
+ {!> ../../../docs_src/dependencies/tutorial008.py!}
+ ```
+
+И все они могут использовать `yield`.
+
+В этом случае `dependency_c` для выполнения своего кода выхода нуждается в том, чтобы значение из `dependency_b` (здесь `dep_b`) было еще доступно.
+
+И, в свою очередь, `dependency_b` нуждается в том, чтобы значение из `dependency_a` (здесь `dep_a`) было доступно для ее завершающего кода.
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="18-19 26-27"
+ {!> ../../../docs_src/dependencies/tutorial008_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="17-18 25-26"
+ {!> ../../../docs_src/dependencies/tutorial008_an.py!}
+ ```
+
+=== "Python 3.6+ без Annotated"
+
+ !!! tip "Подсказка"
+ Предпочтительнее использовать версию с аннотацией, если это возможно.
+
+ ```Python hl_lines="16-17 24-25"
+ {!> ../../../docs_src/dependencies/tutorial008.py!}
+ ```
+
+Точно так же можно иметь часть зависимостей с `yield`, часть с `return`, и какие-то из них могут зависеть друг от друга.
+
+Либо у вас может быть одна зависимость, которая требует несколько других зависимостей с `yield` и т.д.
+
+Комбинации зависимостей могут быть какими вам угодно.
+
+**FastAPI** проследит за тем, чтобы все выполнялось в правильном порядке.
+
+!!! note "Технические детали"
+ Это работает благодаря
Контекстным менеджерам в Python.
+
+ **FastAPI** использует их "под капотом" с этой целью.
+
+## Зависимости с `yield` и `HTTPException`
+
+Вы видели, что можно использовать зависимости с `yield` совместно с блоком `try`, отлавливающие исключения.
+
+Таким же образом вы можете поднять исключение `HTTPException` или что-то подобное в завершающем коде, после `yield`.
+
+Код выхода в зависимостях с `yield` выполняется *после* отправки ответа, поэтому [Обработчик исключений](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} уже будет запущен. В коде выхода (после `yield`) нет ничего, перехватывающего исключения, брошенные вашими зависимостями.
+
+Таким образом, если после `yield` возникает `HTTPException`, то стандартный (или любой пользовательский) обработчик исключений, который перехватывает `HTTPException` и возвращает ответ HTTP 400, уже не сможет перехватить это исключение.
+
+Благодаря этому все, что установлено в зависимости (например, сеанс работы с БД), может быть использовано, например, фоновыми задачами.
+
+Фоновые задачи выполняются *после* отправки ответа. Поэтому нет возможности поднять `HTTPException`, так как нет даже возможности изменить уже отправленный ответ.
+
+Но если фоновая задача создает ошибку в БД, то, по крайней мере, можно сделать откат или чисто закрыть сессию в зависимости с помощью `yield`, а также, возможно, занести ошибку в журнал или сообщить о ней в удаленную систему отслеживания.
+
+Если у вас есть код, который, как вы знаете, может вызвать исключение, сделайте самую обычную/"питонячью" вещь и добавьте блок `try` в этот участок кода.
+
+Если у вас есть пользовательские исключения, которые вы хотите обрабатывать *до* возврата ответа и, возможно, модифицировать ответ, даже вызывая `HTTPException`, создайте [Cобственный обработчик исключений](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
+
+!!! tip "Подсказка"
+ Вы все еще можете вызывать исключения, включая `HTTPException`, *до* `yield`. Но не после.
+
+Последовательность выполнения примерно такая, как на этой схеме. Время течет сверху вниз. А каждый столбец - это одна из частей, взаимодействующих с кодом или выполняющих код.
+
+```mermaid
+sequenceDiagram
+
+participant client as Client
+participant handler as Exception handler
+participant dep as Dep with yield
+participant operation as Path Operation
+participant tasks as Background tasks
+
+ Note over client,tasks: Can raise exception for dependency, handled after response is sent
+ Note over client,operation: Can raise HTTPException and can change the response
+ client ->> dep: Start request
+ Note over dep: Run code up to yield
+ opt raise
+ dep -->> handler: Raise HTTPException
+ handler -->> client: HTTP error response
+ dep -->> dep: Raise other exception
+ end
+ dep ->> operation: Run dependency, e.g. DB session
+ opt raise
+ operation -->> dep: Raise HTTPException
+ dep -->> handler: Auto forward exception
+ handler -->> client: HTTP error response
+ operation -->> dep: Raise other exception
+ dep -->> handler: Auto forward exception
+ end
+ operation ->> client: Return response to client
+ Note over client,operation: Response is already sent, can't change it anymore
+ opt Tasks
+ operation -->> tasks: Send background tasks
+ end
+ opt Raise other exception
+ tasks -->> dep: Raise other exception
+ end
+ Note over dep: After yield
+ opt Handle other exception
+ dep -->> dep: Handle exception, can't change response. E.g. close DB session.
+ end
+```
+
+!!! info "Дополнительная информация"
+ Клиенту будет отправлен только **один ответ**. Это может быть один из ответов об ошибке или это будет ответ от *операции пути*.
+
+ После отправки одного из этих ответов никакой другой ответ не может быть отправлен.
+
+!!! tip "Подсказка"
+ На этой диаграмме показано "HttpException", но вы также можете вызвать любое другое исключение, для которого вы создаете [Пользовательский обработчик исключений](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
+
+ Если вы создадите какое-либо исключение, оно будет передано зависимостям с yield, включая `HttpException`, а затем **снова** обработчикам исключений. Если для этого исключения нет обработчика исключений, то оно будет обработано внутренним "ServerErrorMiddleware" по умолчанию, возвращающим код состояния HTTP 500, чтобы уведомить клиента, что на сервере произошла ошибка.
+
+## Зависимости с `yield`, `HTTPException` и фоновыми задачами
+
+!!! warning "Внимание"
+ Скорее всего, вам не нужны эти технические подробности, вы можете пропустить этот раздел и продолжить ниже.
+
+ Эти подробности полезны, главным образом, если вы использовали версию FastAPI до 0.106.0 и использовали ресурсы из зависимостей с `yield` в фоновых задачах.
+
+До версии FastAPI 0.106.0 вызывать исключения после `yield` было невозможно, код выхода в зависимостях с `yield` выполнялся *после* отправки ответа, поэтому [Обработчик Ошибок](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} уже был бы запущен.
+
+Это было сделано главным образом для того, чтобы позволить использовать те же объекты, "отданные" зависимостями, внутри фоновых задач, поскольку код выхода будет выполняться после завершения фоновых задач.
+
+Тем не менее, поскольку это означало бы ожидание ответа в сети, а также ненужное удержание ресурса в зависимости от доходности (например, соединение с базой данных), это было изменено в FastAPI 0.106.0.
+
+!!! tip "Подсказка"
+
+ Кроме того, фоновая задача обычно представляет собой независимый набор логики, который должен обрабатываться отдельно, со своими собственными ресурсами (например, собственным подключением к базе данных).
+ Таким образом, вы, вероятно, получите более чистый код.
+
+Если вы полагались на это поведение, то теперь вам следует создавать ресурсы для фоновых задач внутри самой фоновой задачи, а внутри использовать только те данные, которые не зависят от ресурсов зависимостей с `yield`.
+
+Например, вместо того чтобы использовать ту же сессию базы данных, вы создадите новую сессию базы данных внутри фоновой задачи и будете получать объекты из базы данных с помощью этой новой сессии. А затем, вместо того чтобы передавать объект из базы данных в качестве параметра в функцию фоновой задачи, вы передадите идентификатор этого объекта, а затем снова получите объект в функции фоновой задачи.
+
+## Контекстные менеджеры
+
+### Что такое "контекстные менеджеры"
+
+"Контекстные менеджеры" - это любые объекты Python, которые можно использовать в операторе `with`.
+
+Например,
можно использовать `with` для чтения файла:
+
+```Python
+with open("./somefile.txt") as f:
+ contents = f.read()
+ print(contents)
+```
+
+Под капотом" open("./somefile.txt") создаёт объект называемый "контекстным менеджером".
+
+Когда блок `with` завершается, он обязательно закрывает файл, даже если были исключения.
+
+Когда вы создаете зависимость с помощью `yield`, **FastAPI** внутренне преобразует ее в контекстный менеджер и объединяет с некоторыми другими связанными инструментами.
+
+### Использование менеджеров контекста в зависимостях с помощью `yield`
+
+!!! warning "Внимание"
+ Это более или менее "продвинутая" идея.
+
+ Если вы только начинаете работать с **FastAPI**, то лучше пока пропустить этот пункт.
+
+В Python для создания менеджеров контекста можно
создать класс с двумя методами: `__enter__()` и `__exit__()`.
+
+Вы также можете использовать их внутри зависимостей **FastAPI** с `yield`, используя операторы
+`with` или `async with` внутри функции зависимости:
+
+```Python hl_lines="1-9 13"
+{!../../../docs_src/dependencies/tutorial010.py!}
+```
+
+!!! tip "Подсказка"
+ Другой способ создания контекстного менеджера - с помощью:
+
+ *
`@contextlib.contextmanager` или
+ *
`@contextlib.asynccontextmanager`
+
+ используйте их для оформления функции с одним `yield`.
+
+ Это то, что **FastAPI** использует внутри себя для зависимостей с `yield`.
+
+ Но использовать декораторы для зависимостей FastAPI не обязательно (да и не стоит).
+
+ FastAPI сделает это за вас на внутреннем уровне.
diff --git a/docs/zh/docs/advanced/generate-clients.md b/docs/zh/docs/advanced/generate-clients.md
index e222e479c..c4ffcb46c 100644
--- a/docs/zh/docs/advanced/generate-clients.md
+++ b/docs/zh/docs/advanced/generate-clients.md
@@ -10,7 +10,7 @@
一个常见的工具是
OpenAPI Generator。
-如果您正在开发**前端**,一个非常有趣的替代方案是
openapi-typescript-codegen。
+如果您正在开发**前端**,一个非常有趣的替代方案是
openapi-ts。
## 生成一个 TypeScript 前端客户端
@@ -46,14 +46,14 @@ OpenAPI中所包含的模型里有相同的信息可以用于 **生成客户端
现在我们有了带有模型的应用,我们可以为前端生成客户端代码。
-#### 安装 `openapi-typescript-codegen`
+#### 安装 `openapi-ts`
-您可以使用以下工具在前端代码中安装 `openapi-typescript-codegen`:
+您可以使用以下工具在前端代码中安装 `openapi-ts`:
```console
-$ npm install openapi-typescript-codegen --save-dev
+$ npm install @hey-api/openapi-ts --save-dev
---> 100%
```
@@ -62,7 +62,7 @@ $ npm install openapi-typescript-codegen --save-dev
#### 生成客户端代码
-要生成客户端代码,您可以使用现在将要安装的命令行应用程序 `openapi`。
+要生成客户端代码,您可以使用现在将要安装的命令行应用程序 `openapi-ts`。
因为它安装在本地项目中,所以您可能无法直接使用此命令,但您可以将其放在 `package.json` 文件中。
@@ -75,12 +75,12 @@ $ npm install openapi-typescript-codegen --save-dev
"description": "",
"main": "index.js",
"scripts": {
- "generate-client": "openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios"
+ "generate-client": "openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios"
},
"author": "",
"license": "",
"devDependencies": {
- "openapi-typescript-codegen": "^0.20.1",
+ "@hey-api/openapi-ts": "^0.27.38",
"typescript": "^4.6.2"
}
}
@@ -94,7 +94,7 @@ $ npm install openapi-typescript-codegen --save-dev
$ npm run generate-client
frontend-app@1.0.0 generate-client /home/user/code/frontend-app
-> openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios
+> openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios
```
@@ -234,12 +234,12 @@ FastAPI为每个*路径操作*使用一个**唯一ID**,它用于**操作ID**
"description": "",
"main": "index.js",
"scripts": {
- "generate-client": "openapi --input ./openapi.json --output ./src/client --client axios"
+ "generate-client": "openapi-ts --input ./openapi.json --output ./src/client --client axios"
},
"author": "",
"license": "",
"devDependencies": {
- "openapi-typescript-codegen": "^0.20.1",
+ "@hey-api/openapi-ts": "^0.27.38",
"typescript": "^4.6.2"
}
}
diff --git a/fastapi/__init__.py b/fastapi/__init__.py
index 234969256..5a77101fb 100644
--- a/fastapi/__init__.py
+++ b/fastapi/__init__.py
@@ -1,6 +1,6 @@
"""FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
-__version__ = "0.110.0"
+__version__ = "0.110.1"
from starlette import status as status
diff --git a/fastapi/applications.py b/fastapi/applications.py
index d3edcc880..4446cacfb 100644
--- a/fastapi/applications.py
+++ b/fastapi/applications.py
@@ -40,7 +40,7 @@ from starlette.requests import Request
from starlette.responses import HTMLResponse, JSONResponse, Response
from starlette.routing import BaseRoute
from starlette.types import ASGIApp, Lifespan, Receive, Scope, Send
-from typing_extensions import Annotated, Doc, deprecated # type: ignore [attr-defined]
+from typing_extensions import Annotated, Doc, deprecated
AppType = TypeVar("AppType", bound="FastAPI")
diff --git a/fastapi/background.py b/fastapi/background.py
index 35ab1b227..203578a41 100644
--- a/fastapi/background.py
+++ b/fastapi/background.py
@@ -1,7 +1,7 @@
from typing import Any, Callable
from starlette.background import BackgroundTasks as StarletteBackgroundTasks
-from typing_extensions import Annotated, Doc, ParamSpec # type: ignore [attr-defined]
+from typing_extensions import Annotated, Doc, ParamSpec
P = ParamSpec("P")
diff --git a/fastapi/datastructures.py b/fastapi/datastructures.py
index ce03e3ce4..cf8406b0f 100644
--- a/fastapi/datastructures.py
+++ b/fastapi/datastructures.py
@@ -24,7 +24,7 @@ from starlette.datastructures import Headers as Headers # noqa: F401
from starlette.datastructures import QueryParams as QueryParams # noqa: F401
from starlette.datastructures import State as State # noqa: F401
from starlette.datastructures import UploadFile as StarletteUploadFile
-from typing_extensions import Annotated, Doc # type: ignore [attr-defined]
+from typing_extensions import Annotated, Doc
class UploadFile(StarletteUploadFile):
diff --git a/fastapi/dependencies/utils.py b/fastapi/dependencies/utils.py
index 02284b4ed..4f984177a 100644
--- a/fastapi/dependencies/utils.py
+++ b/fastapi/dependencies/utils.py
@@ -1,6 +1,6 @@
import inspect
from contextlib import AsyncExitStack, contextmanager
-from copy import deepcopy
+from copy import copy, deepcopy
from typing import (
Any,
Callable,
@@ -384,6 +384,8 @@ def analyze_param(
field_info.annotation = type_annotation
if depends is not None and depends.dependency is None:
+ # Copy `depends` before mutating it
+ depends = copy(depends)
depends.dependency = type_annotation
if lenient_issubclass(
diff --git a/fastapi/encoders.py b/fastapi/encoders.py
index 431387f71..2f9c4a4f7 100644
--- a/fastapi/encoders.py
+++ b/fastapi/encoders.py
@@ -22,7 +22,7 @@ from pydantic import BaseModel
from pydantic.color import Color
from pydantic.networks import AnyUrl, NameEmail
from pydantic.types import SecretBytes, SecretStr
-from typing_extensions import Annotated, Doc # type: ignore [attr-defined]
+from typing_extensions import Annotated, Doc
from ._compat import PYDANTIC_V2, Url, _model_dump
diff --git a/fastapi/exceptions.py b/fastapi/exceptions.py
index 680d288e4..44d4ada86 100644
--- a/fastapi/exceptions.py
+++ b/fastapi/exceptions.py
@@ -3,7 +3,7 @@ from typing import Any, Dict, Optional, Sequence, Type, Union
from pydantic import BaseModel, create_model
from starlette.exceptions import HTTPException as StarletteHTTPException
from starlette.exceptions import WebSocketException as StarletteWebSocketException
-from typing_extensions import Annotated, Doc # type: ignore [attr-defined]
+from typing_extensions import Annotated, Doc
class HTTPException(StarletteHTTPException):
diff --git a/fastapi/openapi/docs.py b/fastapi/openapi/docs.py
index 69473d19c..67815e0fb 100644
--- a/fastapi/openapi/docs.py
+++ b/fastapi/openapi/docs.py
@@ -3,7 +3,7 @@ from typing import Any, Dict, Optional
from fastapi.encoders import jsonable_encoder
from starlette.responses import HTMLResponse
-from typing_extensions import Annotated, Doc # type: ignore [attr-defined]
+from typing_extensions import Annotated, Doc
swagger_ui_default_parameters: Annotated[
Dict[str, Any],
diff --git a/fastapi/param_functions.py b/fastapi/param_functions.py
index 3f6dbc959..6722a7d66 100644
--- a/fastapi/param_functions.py
+++ b/fastapi/param_functions.py
@@ -3,7 +3,7 @@ from typing import Any, Callable, Dict, List, Optional, Sequence, Union
from fastapi import params
from fastapi._compat import Undefined
from fastapi.openapi.models import Example
-from typing_extensions import Annotated, Doc, deprecated # type: ignore [attr-defined]
+from typing_extensions import Annotated, Doc, deprecated
_Unset: Any = Undefined
diff --git a/fastapi/routing.py b/fastapi/routing.py
index 23a32d15f..fa1351859 100644
--- a/fastapi/routing.py
+++ b/fastapi/routing.py
@@ -69,7 +69,7 @@ from starlette.routing import (
from starlette.routing import Mount as Mount # noqa
from starlette.types import ASGIApp, Lifespan, Scope
from starlette.websockets import WebSocket
-from typing_extensions import Annotated, Doc, deprecated # type: ignore [attr-defined]
+from typing_extensions import Annotated, Doc, deprecated
def _prepare_response_content(
diff --git a/fastapi/security/api_key.py b/fastapi/security/api_key.py
index b1a6b4f94..b74a017f1 100644
--- a/fastapi/security/api_key.py
+++ b/fastapi/security/api_key.py
@@ -5,7 +5,7 @@ from fastapi.security.base import SecurityBase
from starlette.exceptions import HTTPException
from starlette.requests import Request
from starlette.status import HTTP_403_FORBIDDEN
-from typing_extensions import Annotated, Doc # type: ignore [attr-defined]
+from typing_extensions import Annotated, Doc
class APIKeyBase(SecurityBase):
diff --git a/fastapi/security/http.py b/fastapi/security/http.py
index 738455de3..b45bee55c 100644
--- a/fastapi/security/http.py
+++ b/fastapi/security/http.py
@@ -10,7 +10,7 @@ from fastapi.security.utils import get_authorization_scheme_param
from pydantic import BaseModel
from starlette.requests import Request
from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN
-from typing_extensions import Annotated, Doc # type: ignore [attr-defined]
+from typing_extensions import Annotated, Doc
class HTTPBasicCredentials(BaseModel):
diff --git a/fastapi/security/oauth2.py b/fastapi/security/oauth2.py
index d7ba44bce..9720cace0 100644
--- a/fastapi/security/oauth2.py
+++ b/fastapi/security/oauth2.py
@@ -10,7 +10,7 @@ from starlette.requests import Request
from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN
# TODO: import from typing when deprecating Python 3.9
-from typing_extensions import Annotated, Doc # type: ignore [attr-defined]
+from typing_extensions import Annotated, Doc
class OAuth2PasswordRequestForm:
diff --git a/fastapi/security/open_id_connect_url.py b/fastapi/security/open_id_connect_url.py
index 1d255877d..c8cceb911 100644
--- a/fastapi/security/open_id_connect_url.py
+++ b/fastapi/security/open_id_connect_url.py
@@ -5,7 +5,7 @@ from fastapi.security.base import SecurityBase
from starlette.exceptions import HTTPException
from starlette.requests import Request
from starlette.status import HTTP_403_FORBIDDEN
-from typing_extensions import Annotated, Doc # type: ignore [attr-defined]
+from typing_extensions import Annotated, Doc
class OpenIdConnect(SecurityBase):
diff --git a/pyproject.toml b/pyproject.toml
index c3801600a..6c3bebf2b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -41,7 +41,7 @@ classifiers = [
"Topic :: Internet :: WWW/HTTP",
]
dependencies = [
- "starlette>=0.36.3,<0.37.0",
+ "starlette>=0.37.2,<0.38.0",
"pydantic>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0",
"typing-extensions>=4.8.0",
]
@@ -121,9 +121,6 @@ filterwarnings = [
# - https://github.com/mpdavis/python-jose/issues/332
# - https://github.com/mpdavis/python-jose/issues/334
'ignore:datetime\.datetime\.utcnow\(\) is deprecated and scheduled for removal in a future version\..*:DeprecationWarning:jose',
- # TODO: remove after upgrading Starlette to a version including https://github.com/encode/starlette/pull/2406
- # Probably Starlette 0.36.0
- "ignore: The 'method' parameter is not used, and it will be removed.:DeprecationWarning:starlette",
]
[tool.coverage.run]
diff --git a/requirements-docs.txt b/requirements-docs.txt
index a97f988cb..8fa64cf39 100644
--- a/requirements-docs.txt
+++ b/requirements-docs.txt
@@ -3,17 +3,16 @@
mkdocs-material==9.4.7
mdx-include >=1.4.1,<2.0.0
mkdocs-redirects>=1.2.1,<1.3.0
-typer-cli >=0.0.13,<0.0.14
-typer[all] >=0.6.1,<0.8.0
+typer >=0.12.0
pyyaml >=5.3.1,<7.0.0
# For Material for MkDocs, Chinese search
jieba==0.42.1
# For image processing by Material for MkDocs
-pillow==10.1.0
+pillow==10.2.0
# For image processing by Material for MkDocs
cairosvg==2.7.0
mkdocstrings[python]==0.23.0
griffe-typingdoc==0.2.2
# For griffe, it formats with black
-black==23.3.0
+black==24.3.0
mkdocs-macros-plugin==1.0.5
diff --git a/requirements-tests.txt b/requirements-tests.txt
index 09ca9cb52..30762bc64 100644
--- a/requirements-tests.txt
+++ b/requirements-tests.txt
@@ -3,7 +3,7 @@
pydantic-settings >=2.0.0
pytest >=7.1.3,<8.0.0
coverage[toml] >= 6.5.0,< 8.0
-mypy ==1.4.1
+mypy ==1.8.0
ruff ==0.2.0
email_validator >=1.1.1,<3.0.0
dirty-equals ==0.6.0
diff --git a/tests/test_generic_parameterless_depends.py b/tests/test_generic_parameterless_depends.py
new file mode 100644
index 000000000..fe13ff89b
--- /dev/null
+++ b/tests/test_generic_parameterless_depends.py
@@ -0,0 +1,77 @@
+from typing import TypeVar
+
+from fastapi import Depends, FastAPI
+from fastapi.testclient import TestClient
+from typing_extensions import Annotated
+
+app = FastAPI()
+
+T = TypeVar("T")
+
+Dep = Annotated[T, Depends()]
+
+
+class A:
+ pass
+
+
+class B:
+ pass
+
+
+@app.get("/a")
+async def a(dep: Dep[A]):
+ return {"cls": dep.__class__.__name__}
+
+
+@app.get("/b")
+async def b(dep: Dep[B]):
+ return {"cls": dep.__class__.__name__}
+
+
+client = TestClient(app)
+
+
+def test_generic_parameterless_depends():
+ response = client.get("/a")
+ assert response.status_code == 200, response.text
+ assert response.json() == {"cls": "A"}
+
+ response = client.get("/b")
+ assert response.status_code == 200, response.text
+ assert response.json() == {"cls": "B"}
+
+
+def test_openapi_schema():
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == {
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "openapi": "3.1.0",
+ "paths": {
+ "/a": {
+ "get": {
+ "operationId": "a_a_get",
+ "responses": {
+ "200": {
+ "content": {"application/json": {"schema": {}}},
+ "description": "Successful " "Response",
+ }
+ },
+ "summary": "A",
+ }
+ },
+ "/b": {
+ "get": {
+ "operationId": "b_b_get",
+ "responses": {
+ "200": {
+ "content": {"application/json": {"schema": {}}},
+ "description": "Successful " "Response",
+ }
+ },
+ "summary": "B",
+ }
+ },
+ },
+ }