Browse Source
Add full Urdu translation of FastAPI documentation (155 files): - docs/ur/mkdocs.yml — config inheriting from English - docs/ur/llm-prompt.md — Urdu translation guidelines and glossary - docs/ur/docs/translation-banner.md — Urdu translation notice - docs/ur/docs/index.md — Landing page - docs/ur/docs/tutorial/ — Complete tutorial (39 files) - docs/ur/docs/advanced/ — Complete advanced guide (26 files) - docs/ur/docs/deployment/ — Complete deployment guide (9 files) - docs/ur/docs/how-to/ — Complete how-to recipes (12 files) - docs/ur/docs/reference/ — Complete API reference (23 files) - docs/ur/docs/ — All root-level docs (features, async, alternatives, etc.) Translation approach: - Natural, fluent Urdu — not word-by-word - Technical terms kept in English (path, route, request, response, etc.) - All code blocks, URLs, and markdown structure preserved - Admonition titles in canonical Urdu Co-Authored-By: Claude Opus 4.6 <[email protected]>pull/15117/head
155 changed files with 20618 additions and 0 deletions
@ -0,0 +1,503 @@ |
|||||
|
# LLM ٹیسٹ فائل { #llm-test-file } |
||||
|
|
||||
|
یہ document ٹیسٹ کرتا ہے کہ آیا <abbr title="Large Language Model">LLM</abbr>، جو documentation کا ترجمہ کرتا ہے، `scripts/translate.py` میں `general_prompt` اور `docs/{language code}/llm-prompt.md` میں زبان کے لیے مخصوص prompt کو سمجھتا ہے۔ زبان کے لیے مخصوص prompt، `general_prompt` کے ساتھ جوڑا جاتا ہے۔ |
||||
|
|
||||
|
یہاں شامل کیے گئے ٹیسٹ تمام زبان کے مخصوص prompt ڈیزائنرز کو نظر آئیں گے۔ |
||||
|
|
||||
|
اس طرح استعمال کریں: |
||||
|
|
||||
|
* زبان کے لیے مخصوص prompt رکھیں - `docs/{language code}/llm-prompt.md`۔ |
||||
|
* اس document کا اپنی مطلوبہ ہدف زبان میں تازہ ترجمہ کریں (مثلاً `translate.py` کا `translate-page` command دیکھیں)۔ یہ `docs/{language code}/docs/_llm-test.md` کے تحت ترجمہ بنائے گا۔ |
||||
|
* چیک کریں کہ ترجمے میں سب ٹھیک ہے۔ |
||||
|
* اگر ضروری ہو تو اپنے زبان کے مخصوص prompt، عمومی prompt، یا انگریزی document کو بہتر بنائیں۔ |
||||
|
* پھر ترجمے میں باقی رہ جانے والے مسائل خود ٹھیک کریں، تاکہ یہ اچھا ترجمہ ہو۔ |
||||
|
* اچھا ترجمہ موجود ہونے کے بعد دوبارہ ترجمہ کریں۔ مثالی نتیجہ یہ ہوگا کہ LLM ترجمے میں مزید کوئی تبدیلی نہ کرے۔ اس کا مطلب ہے کہ عمومی prompt اور آپ کا زبان کے مخصوص prompt اتنے اچھے ہیں جتنے ہو سکتے ہیں (یہ بعض اوقات کچھ بظاہر بے ترتیب تبدیلیاں کرے گا، اس کی وجہ یہ ہے کہ [LLMs deterministic algorithms نہیں ہیں](https://doublespeak.chat/#/handbook#deterministic-output))۔ |
||||
|
|
||||
|
ٹیسٹ: |
||||
|
|
||||
|
## Code snippets { #code-snippets } |
||||
|
|
||||
|
//// tab | Test |
||||
|
|
||||
|
یہ ایک code snippet ہے: `foo`۔ اور یہ ایک اور code snippet ہے: `bar`۔ اور ایک اور: `baz quux`۔ |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Info |
||||
|
|
||||
|
Code snippets کا مواد جوں کا توں رہنا چاہیے۔ |
||||
|
|
||||
|
`scripts/translate.py` میں عمومی prompt کا سیکشن `### Content of code snippets` دیکھیں۔ |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
## اقتباسات { #quotes } |
||||
|
|
||||
|
//// tab | Test |
||||
|
|
||||
|
کل میرے دوست نے لکھا: "If you spell incorrectly correctly, you have spelled it incorrectly"۔ جس پر میں نے جواب دیا: "Correct, but 'incorrectly' is incorrectly not '"incorrectly"'"۔ |
||||
|
|
||||
|
/// note | نوٹ |
||||
|
|
||||
|
LLM شاید اس کا ترجمہ غلط کرے گا۔ دلچسپ صرف یہ ہے کہ دوبارہ ترجمہ کرتے وقت یہ ٹھیک کیا گیا ترجمہ محفوظ رکھتا ہے یا نہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Info |
||||
|
|
||||
|
Prompt ڈیزائنر یہ فیصلہ کر سکتا ہے کہ آیا وہ neutral quotes کو typographic quotes میں تبدیل کرنا چاہتے ہیں۔ انہیں جوں کا توں چھوڑنا بھی ٹھیک ہے۔ |
||||
|
|
||||
|
مثال کے طور پر `docs/de/llm-prompt.md` میں سیکشن `### Quotes` دیکھیں۔ |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
## Code snippets میں اقتباسات { #quotes-in-code-snippets } |
||||
|
|
||||
|
//// tab | Test |
||||
|
|
||||
|
`pip install "foo[bar]"` |
||||
|
|
||||
|
Code snippets میں string literals کی مثالیں: `"this"`, `'that'`۔ |
||||
|
|
||||
|
Code snippets میں string literals کی مشکل مثال: `f"I like {'oranges' if orange else "apples"}"` |
||||
|
|
||||
|
سخت ترین: `Yesterday, my friend wrote: "If you spell incorrectly correctly, you have spelled it incorrectly". To which I answered: "Correct, but 'incorrectly' is incorrectly not '"incorrectly"'"` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Info |
||||
|
|
||||
|
... تاہم، code snippets کے اندر اقتباسات جوں کے توں رہنے چاہئیں۔ |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
## Code blocks { #code-blocks } |
||||
|
|
||||
|
//// tab | Test |
||||
|
|
||||
|
ایک Bash code مثال... |
||||
|
|
||||
|
```bash |
||||
|
# Print a greeting to the universe |
||||
|
echo "Hello universe" |
||||
|
``` |
||||
|
|
||||
|
...اور ایک console code مثال... |
||||
|
|
||||
|
```console |
||||
|
$ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:solid">main.py</u> |
||||
|
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting server |
||||
|
Searching for package file structure |
||||
|
``` |
||||
|
|
||||
|
...اور ایک اور console code مثال... |
||||
|
|
||||
|
```console |
||||
|
// "Code" نامی directory بنائیں |
||||
|
$ mkdir code |
||||
|
// اس directory میں جائیں |
||||
|
$ cd code |
||||
|
``` |
||||
|
|
||||
|
...اور ایک Python code مثال... |
||||
|
|
||||
|
```Python |
||||
|
wont_work() # This won't work 😱 |
||||
|
works(foo="bar") # This works 🎉 |
||||
|
``` |
||||
|
|
||||
|
...اور بس۔ |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Info |
||||
|
|
||||
|
Code blocks میں code کو تبدیل نہیں کیا جانا چاہیے، سوائے تبصروں کے۔ |
||||
|
|
||||
|
`scripts/translate.py` میں عمومی prompt کا سیکشن `### Content of code blocks` دیکھیں۔ |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
## Tabs اور رنگین خانے { #tabs-and-colored-boxes } |
||||
|
|
||||
|
//// tab | Test |
||||
|
|
||||
|
/// info | معلومات |
||||
|
کچھ متن |
||||
|
/// |
||||
|
|
||||
|
/// note | نوٹ |
||||
|
کچھ متن |
||||
|
/// |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
کچھ متن |
||||
|
/// |
||||
|
|
||||
|
/// check |
||||
|
کچھ متن |
||||
|
/// |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
کچھ متن |
||||
|
/// |
||||
|
|
||||
|
/// warning | انتباہ |
||||
|
کچھ متن |
||||
|
/// |
||||
|
|
||||
|
/// danger |
||||
|
کچھ متن |
||||
|
/// |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Info |
||||
|
|
||||
|
Tabs اور `Info`/`Note`/`Warning` وغیرہ بلاکس میں عمودی خط (`|`) کے بعد ان کے عنوان کا ترجمہ شامل ہونا چاہیے۔ |
||||
|
|
||||
|
`scripts/translate.py` میں عمومی prompt کے سیکشنز `### Special blocks` اور `### Tab blocks` دیکھیں۔ |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
## Web اور اندرونی لنکس { #web-and-internal-links } |
||||
|
|
||||
|
//// tab | Test |
||||
|
|
||||
|
لنک کا متن ترجمہ ہونا چاہیے، لنک کا پتہ تبدیل نہیں ہونا چاہیے: |
||||
|
|
||||
|
* [اوپر والی heading کا لنک](#code-snippets) |
||||
|
* [اندرونی لنک](index.md#installation) |
||||
|
* [بیرونی لنک](https://sqlmodel.tiangolo.com/) |
||||
|
* [ایک style کا لنک](https://fastapi.tiangolo.com/css/styles.css) |
||||
|
* [ایک script کا لنک](https://fastapi.tiangolo.com/js/logic.js) |
||||
|
* [ایک تصویر کا لنک](https://fastapi.tiangolo.com/img/foo.jpg) |
||||
|
|
||||
|
لنک کا متن ترجمہ ہونا چاہیے، لنک کا پتہ ترجمے کی طرف اشارہ کرنا چاہیے: |
||||
|
|
||||
|
* [FastAPI لنک](https://fastapi.tiangolo.com/) |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Info |
||||
|
|
||||
|
لنکس کا ترجمہ ہونا چاہیے، لیکن ان کا پتہ تبدیل نہیں ہونا چاہیے۔ استثناء FastAPI documentation کے صفحات کے مطلق لنکس ہیں۔ اس صورت میں اسے ترجمے کی طرف لنک کرنا چاہیے۔ |
||||
|
|
||||
|
`scripts/translate.py` میں عمومی prompt کا سیکشن `### Links` دیکھیں۔ |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
## HTML "abbr" عناصر { #html-abbr-elements } |
||||
|
|
||||
|
//// tab | Test |
||||
|
|
||||
|
یہاں HTML "abbr" عناصر میں لپٹی کچھ چیزیں ہیں (کچھ من گھڑت ہیں): |
||||
|
|
||||
|
### abbr مکمل جملہ دیتا ہے { #the-abbr-gives-a-full-phrase } |
||||
|
|
||||
|
* <abbr title="Getting Things Done">GTD</abbr> |
||||
|
* <abbr title="less than"><code>lt</code></abbr> |
||||
|
* <abbr title="XML Web Token">XWT</abbr> |
||||
|
* <abbr title="Parallel Server Gateway Interface">PSGI</abbr> |
||||
|
|
||||
|
### abbr مکمل جملہ اور وضاحت دیتا ہے { #the-abbr-gives-a-full-phrase-and-an-explanation } |
||||
|
|
||||
|
* <abbr title="Mozilla Developer Network: documentation for developers, written by the Firefox people">MDN</abbr> |
||||
|
* <abbr title="Input/Output: disk reading or writing, network communications.">I/O</abbr>. |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Info |
||||
|
|
||||
|
"abbr" عناصر کی "title" attributes کا مخصوص ہدایات کے مطابق ترجمہ کیا جاتا ہے۔ |
||||
|
|
||||
|
تراجم اپنے "abbr" عناصر شامل کر سکتے ہیں جنہیں LLM نہیں ہٹانا چاہیے۔ مثلاً انگریزی الفاظ کی وضاحت کے لیے۔ |
||||
|
|
||||
|
`scripts/translate.py` میں عمومی prompt کا سیکشن `### HTML abbr elements` دیکھیں۔ |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
## HTML "dfn" عناصر { #html-dfn-elements } |
||||
|
|
||||
|
* <dfn title="A group of machines that are configured to be connected and work together in some way.">cluster</dfn> |
||||
|
* <dfn title="A method of machine learning that uses artificial neural networks with numerous hidden layers between input and output layers, thereby developing a comprehensive internal structure">Deep Learning</dfn> |
||||
|
|
||||
|
## عنوانات { #headings } |
||||
|
|
||||
|
//// tab | Test |
||||
|
|
||||
|
### ایک webapp تیار کریں - ایک tutorial { #develop-a-webapp-a-tutorial } |
||||
|
|
||||
|
ہیلو۔ |
||||
|
|
||||
|
### Type hints اور -annotations { #type-hints-and-annotations } |
||||
|
|
||||
|
دوبارہ ہیلو۔ |
||||
|
|
||||
|
### Super- اور subclasses { #super-and-subclasses } |
||||
|
|
||||
|
دوبارہ ہیلو۔ |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Info |
||||
|
|
||||
|
عنوانات کے لیے واحد سخت قاعدہ یہ ہے کہ LLM گھنگھریالے قوسین کے اندر hash حصے کو تبدیل نہ کرے، جو یقینی بناتا ہے کہ لنکس نہ ٹوٹیں۔ |
||||
|
|
||||
|
`scripts/translate.py` میں عمومی prompt کا سیکشن `### Headings` دیکھیں۔ |
||||
|
|
||||
|
کچھ زبان کے مخصوص ہدایات کے لیے، مثلاً `docs/de/llm-prompt.md` میں سیکشن `### Headings` دیکھیں۔ |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
## Docs میں استعمال ہونے والی اصطلاحات { #terms-used-in-the-docs } |
||||
|
|
||||
|
//// tab | Test |
||||
|
|
||||
|
* you |
||||
|
* your |
||||
|
|
||||
|
* e.g. |
||||
|
* etc. |
||||
|
|
||||
|
* `foo` as an `int` |
||||
|
* `bar` as a `str` |
||||
|
* `baz` as a `list` |
||||
|
|
||||
|
* the Tutorial - User guide |
||||
|
* the Advanced User Guide |
||||
|
* the SQLModel docs |
||||
|
* the API docs |
||||
|
* the automatic docs |
||||
|
|
||||
|
* Data Science |
||||
|
* Deep Learning |
||||
|
* Machine Learning |
||||
|
* Dependency Injection |
||||
|
* HTTP Basic authentication |
||||
|
* HTTP Digest |
||||
|
* ISO format |
||||
|
* the JSON Schema standard |
||||
|
* the JSON schema |
||||
|
* the schema definition |
||||
|
* Password Flow |
||||
|
* Mobile |
||||
|
|
||||
|
* deprecated |
||||
|
* designed |
||||
|
* invalid |
||||
|
* on the fly |
||||
|
* standard |
||||
|
* default |
||||
|
* case-sensitive |
||||
|
* case-insensitive |
||||
|
|
||||
|
* to serve the application |
||||
|
* to serve the page |
||||
|
|
||||
|
* the app |
||||
|
* the application |
||||
|
|
||||
|
* the request |
||||
|
* the response |
||||
|
* the error response |
||||
|
|
||||
|
* the path operation |
||||
|
* the path operation decorator |
||||
|
* the path operation function |
||||
|
|
||||
|
* the body |
||||
|
* the request body |
||||
|
* the response body |
||||
|
* the JSON body |
||||
|
* the form body |
||||
|
* the file body |
||||
|
* the function body |
||||
|
|
||||
|
* the parameter |
||||
|
* the body parameter |
||||
|
* the path parameter |
||||
|
* the query parameter |
||||
|
* the cookie parameter |
||||
|
* the header parameter |
||||
|
* the form parameter |
||||
|
* the function parameter |
||||
|
|
||||
|
* the event |
||||
|
* the startup event |
||||
|
* the startup of the server |
||||
|
* the shutdown event |
||||
|
* the lifespan event |
||||
|
|
||||
|
* the handler |
||||
|
* the event handler |
||||
|
* the exception handler |
||||
|
* to handle |
||||
|
|
||||
|
* the model |
||||
|
* the Pydantic model |
||||
|
* the data model |
||||
|
* the database model |
||||
|
* the form model |
||||
|
* the model object |
||||
|
|
||||
|
* the class |
||||
|
* the base class |
||||
|
* the parent class |
||||
|
* the subclass |
||||
|
* the child class |
||||
|
* the sibling class |
||||
|
* the class method |
||||
|
|
||||
|
* the header |
||||
|
* the headers |
||||
|
* the authorization header |
||||
|
* the `Authorization` header |
||||
|
* the forwarded header |
||||
|
|
||||
|
* the dependency injection system |
||||
|
* the dependency |
||||
|
* the dependable |
||||
|
* the dependant |
||||
|
|
||||
|
* I/O bound |
||||
|
* CPU bound |
||||
|
* concurrency |
||||
|
* parallelism |
||||
|
* multiprocessing |
||||
|
|
||||
|
* the env var |
||||
|
* the environment variable |
||||
|
* the `PATH` |
||||
|
* the `PATH` variable |
||||
|
|
||||
|
* the authentication |
||||
|
* the authentication provider |
||||
|
* the authorization |
||||
|
* the authorization form |
||||
|
* the authorization provider |
||||
|
* the user authenticates |
||||
|
* the system authenticates the user |
||||
|
|
||||
|
* the CLI |
||||
|
* the command line interface |
||||
|
|
||||
|
* the server |
||||
|
* the client |
||||
|
|
||||
|
* the cloud provider |
||||
|
* the cloud service |
||||
|
|
||||
|
* the development |
||||
|
* the development stages |
||||
|
|
||||
|
* the dict |
||||
|
* the dictionary |
||||
|
* the enumeration |
||||
|
* the enum |
||||
|
* the enum member |
||||
|
|
||||
|
* the encoder |
||||
|
* the decoder |
||||
|
* to encode |
||||
|
* to decode |
||||
|
|
||||
|
* the exception |
||||
|
* to raise |
||||
|
|
||||
|
* the expression |
||||
|
* the statement |
||||
|
|
||||
|
* the frontend |
||||
|
* the backend |
||||
|
|
||||
|
* the GitHub discussion |
||||
|
* the GitHub issue |
||||
|
|
||||
|
* the performance |
||||
|
* the performance optimization |
||||
|
|
||||
|
* the return type |
||||
|
* the return value |
||||
|
|
||||
|
* the security |
||||
|
* the security scheme |
||||
|
|
||||
|
* the task |
||||
|
* the background task |
||||
|
* the task function |
||||
|
|
||||
|
* the template |
||||
|
* the template engine |
||||
|
|
||||
|
* the type annotation |
||||
|
* the type hint |
||||
|
|
||||
|
* the server worker |
||||
|
* the Uvicorn worker |
||||
|
* the Gunicorn Worker |
||||
|
* the worker process |
||||
|
* the worker class |
||||
|
* the workload |
||||
|
|
||||
|
* the deployment |
||||
|
* to deploy |
||||
|
|
||||
|
* the SDK |
||||
|
* the software development kit |
||||
|
|
||||
|
* the `APIRouter` |
||||
|
* the `requirements.txt` |
||||
|
* the Bearer Token |
||||
|
* the breaking change |
||||
|
* the bug |
||||
|
* the button |
||||
|
* the callable |
||||
|
* the code |
||||
|
* the commit |
||||
|
* the context manager |
||||
|
* the coroutine |
||||
|
* the database session |
||||
|
* the disk |
||||
|
* the domain |
||||
|
* the engine |
||||
|
* the fake X |
||||
|
* the HTTP GET method |
||||
|
* the item |
||||
|
* the library |
||||
|
* the lifespan |
||||
|
* the lock |
||||
|
* the middleware |
||||
|
* the mobile application |
||||
|
* the module |
||||
|
* the mounting |
||||
|
* the network |
||||
|
* the origin |
||||
|
* the override |
||||
|
* the payload |
||||
|
* the processor |
||||
|
* the property |
||||
|
* the proxy |
||||
|
* the pull request |
||||
|
* the query |
||||
|
* the RAM |
||||
|
* the remote machine |
||||
|
* the status code |
||||
|
* the string |
||||
|
* the tag |
||||
|
* the web framework |
||||
|
* the wildcard |
||||
|
* to return |
||||
|
* to validate |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Info |
||||
|
|
||||
|
یہ docs میں نظر آنے والی (زیادہ تر) تکنیکی اصطلاحات کی ایک نامکمل اور غیر حتمی فہرست ہے۔ یہ prompt ڈیزائنر کے لیے مفید ہو سکتی ہے تاکہ معلوم ہو کہ کن اصطلاحات کے لیے LLM کو مدد کی ضرورت ہے۔ مثلاً جب یہ اچھے ترجمے کو بار بار کسی کمتر ترجمے میں واپس لے آئے۔ یا جب اسے آپ کی زبان میں کسی اصطلاح کو conjugate/declinate کرنے میں مسائل ہوں۔ |
||||
|
|
||||
|
مثال کے طور پر `docs/de/llm-prompt.md` میں سیکشن `### List of English terms and their preferred German translations` دیکھیں۔ |
||||
|
|
||||
|
//// |
||||
@ -0,0 +1,3 @@ |
|||||
|
# کے بارے میں { #about } |
||||
|
|
||||
|
FastAPI کے بارے میں، اس کی ڈیزائن، الہام اور مزید۔ 🤓 |
||||
@ -0,0 +1,247 @@ |
|||||
|
# OpenAPI میں اضافی Responses { #additional-responses-in-openapi } |
||||
|
|
||||
|
/// warning | انتباہ |
||||
|
|
||||
|
یہ ایک کافی ایڈوانسڈ موضوع ہے۔ |
||||
|
|
||||
|
اگر آپ **FastAPI** کے ساتھ شروعات کر رہے ہیں تو آپ کو شاید اس کی ضرورت نہ ہو۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
آپ اضافی responses کا اعلان کر سکتے ہیں، اضافی status codes، media types، وضاحتوں وغیرہ کے ساتھ۔ |
||||
|
|
||||
|
یہ اضافی responses OpenAPI schema میں شامل کیے جائیں گے، لہذا وہ API docs میں بھی ظاہر ہوں گے۔ |
||||
|
|
||||
|
لیکن ان اضافی responses کے لیے آپ کو یقینی بنانا ہوگا کہ آپ براہ راست `Response` جیسے `JSONResponse` واپس کریں، اپنے status code اور مواد کے ساتھ۔ |
||||
|
|
||||
|
## `model` کے ساتھ اضافی Response { #additional-response-with-model } |
||||
|
|
||||
|
آپ اپنے *path operation decorators* کو ایک parameter `responses` دے سکتے ہیں۔ |
||||
|
|
||||
|
یہ ایک `dict` وصول کرتا ہے: کلیدیں ہر response کے لیے status codes ہیں (جیسے `200`)، اور قدریں دوسری `dict` ہیں جن میں ہر ایک کی معلومات ہوتی ہیں۔ |
||||
|
|
||||
|
ان response `dict` میں سے ہر ایک میں `model` نامی ایک کلید ہو سکتی ہے، جس میں Pydantic model ہوتا ہے، بالکل `response_model` کی طرح۔ |
||||
|
|
||||
|
**FastAPI** اس model کو لے گا، اس کا JSON Schema تیار کرے گا اور اسے OpenAPI میں صحیح جگہ شامل کرے گا۔ |
||||
|
|
||||
|
مثال کے طور پر، status code `404` اور Pydantic model `Message` کے ساتھ ایک اور response کا اعلان کرنے کے لیے، آپ یہ لکھ سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/additional_responses/tutorial001_py310.py hl[18,22] *} |
||||
|
|
||||
|
/// note | نوٹ |
||||
|
|
||||
|
ذہن میں رکھیں کہ آپ کو `JSONResponse` براہ راست واپس کرنا ہوگا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
`model` کلید OpenAPI کا حصہ نہیں ہے۔ |
||||
|
|
||||
|
**FastAPI** وہاں سے Pydantic model لے گا، JSON Schema تیار کرے گا، اور اسے صحیح جگہ رکھے گا۔ |
||||
|
|
||||
|
صحیح جگہ یہ ہے: |
||||
|
|
||||
|
* کلید `content` میں، جس کی قدر ایک اور JSON object (`dict`) ہے جس میں شامل ہے: |
||||
|
* media type والی ایک کلید، مثلاً `application/json`، جس کی قدر ایک اور JSON object ہے، جس میں شامل ہے: |
||||
|
* ایک کلید `schema`، جس کی قدر model سے JSON Schema ہے، یہ ہے صحیح جگہ۔ |
||||
|
* **FastAPI** یہاں عالمی JSON Schemas کا حوالہ شامل کرتا ہے جو آپ کے OpenAPI میں کسی اور جگہ ہوتے ہیں بجائے اسے براہ راست شامل کرنے کے۔ اس طرح، دوسری ایپلیکیشنز اور clients ان JSON Schemas کو براہ راست استعمال کر سکتے ہیں، بہتر code generation ٹولز فراہم کر سکتے ہیں وغیرہ۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
اس *path operation* کے لیے OpenAPI میں تیار شدہ responses یہ ہوں گے: |
||||
|
|
||||
|
```JSON hl_lines="3-12" |
||||
|
{ |
||||
|
"responses": { |
||||
|
"404": { |
||||
|
"description": "Additional Response", |
||||
|
"content": { |
||||
|
"application/json": { |
||||
|
"schema": { |
||||
|
"$ref": "#/components/schemas/Message" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"200": { |
||||
|
"description": "Successful Response", |
||||
|
"content": { |
||||
|
"application/json": { |
||||
|
"schema": { |
||||
|
"$ref": "#/components/schemas/Item" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"422": { |
||||
|
"description": "Validation Error", |
||||
|
"content": { |
||||
|
"application/json": { |
||||
|
"schema": { |
||||
|
"$ref": "#/components/schemas/HTTPValidationError" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
Schemas کا حوالہ OpenAPI schema کے اندر کسی اور جگہ دیا گیا ہے: |
||||
|
|
||||
|
```JSON hl_lines="4-16" |
||||
|
{ |
||||
|
"components": { |
||||
|
"schemas": { |
||||
|
"Message": { |
||||
|
"title": "Message", |
||||
|
"required": [ |
||||
|
"message" |
||||
|
], |
||||
|
"type": "object", |
||||
|
"properties": { |
||||
|
"message": { |
||||
|
"title": "Message", |
||||
|
"type": "string" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"Item": { |
||||
|
"title": "Item", |
||||
|
"required": [ |
||||
|
"id", |
||||
|
"value" |
||||
|
], |
||||
|
"type": "object", |
||||
|
"properties": { |
||||
|
"id": { |
||||
|
"title": "Id", |
||||
|
"type": "string" |
||||
|
}, |
||||
|
"value": { |
||||
|
"title": "Value", |
||||
|
"type": "string" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"ValidationError": { |
||||
|
"title": "ValidationError", |
||||
|
"required": [ |
||||
|
"loc", |
||||
|
"msg", |
||||
|
"type" |
||||
|
], |
||||
|
"type": "object", |
||||
|
"properties": { |
||||
|
"loc": { |
||||
|
"title": "Location", |
||||
|
"type": "array", |
||||
|
"items": { |
||||
|
"type": "string" |
||||
|
} |
||||
|
}, |
||||
|
"msg": { |
||||
|
"title": "Message", |
||||
|
"type": "string" |
||||
|
}, |
||||
|
"type": { |
||||
|
"title": "Error Type", |
||||
|
"type": "string" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"HTTPValidationError": { |
||||
|
"title": "HTTPValidationError", |
||||
|
"type": "object", |
||||
|
"properties": { |
||||
|
"detail": { |
||||
|
"title": "Detail", |
||||
|
"type": "array", |
||||
|
"items": { |
||||
|
"$ref": "#/components/schemas/ValidationError" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
## بنیادی response کے لیے اضافی media types { #additional-media-types-for-the-main-response } |
||||
|
|
||||
|
آپ اسی `responses` parameter کو استعمال کر کے بنیادی response میں مختلف media types شامل کر سکتے ہیں۔ |
||||
|
|
||||
|
مثال کے طور پر، آپ `image/png` کی اضافی media type شامل کر سکتے ہیں، یہ اعلان کرتے ہوئے کہ آپ کا *path operation* ایک JSON object (media type `application/json` کے ساتھ) یا PNG تصویر واپس کر سکتا ہے: |
||||
|
|
||||
|
{* ../../docs_src/additional_responses/tutorial002_py310.py hl[17:22,26] *} |
||||
|
|
||||
|
/// note | نوٹ |
||||
|
|
||||
|
دھیان دیں کہ آپ کو تصویر براہ راست `FileResponse` استعمال کر کے واپس کرنی ہوگی۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
جب تک آپ اپنے `responses` parameter میں واضح طور پر کوئی مختلف media type بیان نہیں کرتے، FastAPI فرض کرے گا کہ response کی media type بنیادی response class جیسی ہی ہے (پہلے سے طے شدہ `application/json`)۔ |
||||
|
|
||||
|
لیکن اگر آپ نے `None` کو اس کی media type کے طور پر اپنی مرضی کی response class بیان کی ہے، تو FastAPI کسی بھی اضافی response کے لیے `application/json` استعمال کرے گا جس کے ساتھ ایک model منسلک ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## معلومات کو یکجا کرنا { #combining-information } |
||||
|
|
||||
|
آپ متعدد جگہوں سے response کی معلومات کو بھی یکجا کر سکتے ہیں، بشمول `response_model`، `status_code`، اور `responses` parameters۔ |
||||
|
|
||||
|
آپ `response_model` کا اعلان کر سکتے ہیں، پہلے سے طے شدہ status code `200` (یا ضرورت کے مطابق کوئی اور) استعمال کرتے ہوئے، اور پھر اسی response کے لیے `responses` میں اضافی معلومات کا اعلان کر سکتے ہیں، براہ راست OpenAPI schema میں۔ |
||||
|
|
||||
|
**FastAPI** `responses` سے اضافی معلومات رکھے گا، اور اسے آپ کے model سے JSON Schema کے ساتھ ملا دے گا۔ |
||||
|
|
||||
|
مثال کے طور پر، آپ status code `404` والا response اعلان کر سکتے ہیں جو Pydantic model استعمال کرتا ہے اور اپنی مرضی کی `description` رکھتا ہے۔ |
||||
|
|
||||
|
اور status code `200` والا response جو آپ کا `response_model` استعمال کرتا ہے، لیکن اپنی مرضی کی `example` شامل کرتا ہے: |
||||
|
|
||||
|
{* ../../docs_src/additional_responses/tutorial003_py310.py hl[20:31] *} |
||||
|
|
||||
|
یہ سب یکجا ہو کر آپ کے OpenAPI میں شامل ہو جائے گا، اور API docs میں دکھایا جائے گا: |
||||
|
|
||||
|
<img src="/img/tutorial/additional-responses/image01.png"> |
||||
|
|
||||
|
## پہلے سے طے شدہ اور اپنی مرضی کے responses کو ملانا { #combine-predefined-responses-and-custom-ones } |
||||
|
|
||||
|
ہو سکتا ہے آپ چاہیں کہ کچھ پہلے سے طے شدہ responses ہوں جو بہت سے *path operations* پر لاگو ہوں، لیکن آپ انہیں ہر *path operation* کے لیے درکار اپنی مرضی کے responses کے ساتھ ملانا چاہتے ہیں۔ |
||||
|
|
||||
|
ان صورتوں میں، آپ Python کی `dict` کو `**dict_to_unpack` کے ساتھ "unpack" کرنے کی تکنیک استعمال کر سکتے ہیں: |
||||
|
|
||||
|
```Python |
||||
|
old_dict = { |
||||
|
"old key": "old value", |
||||
|
"second old key": "second old value", |
||||
|
} |
||||
|
new_dict = {**old_dict, "new key": "new value"} |
||||
|
``` |
||||
|
|
||||
|
یہاں، `new_dict` میں `old_dict` کے تمام key-value جوڑے اور نیا key-value جوڑا شامل ہوگا: |
||||
|
|
||||
|
```Python |
||||
|
{ |
||||
|
"old key": "old value", |
||||
|
"second old key": "second old value", |
||||
|
"new key": "new value", |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
آپ اس تکنیک کو اپنے *path operations* میں پہلے سے طے شدہ responses کو دوبارہ استعمال کرنے اور انہیں اضافی اپنی مرضی کے responses کے ساتھ ملانے کے لیے استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
مثال کے طور پر: |
||||
|
|
||||
|
{* ../../docs_src/additional_responses/tutorial004_py310.py hl[11:15,24] *} |
||||
|
|
||||
|
## OpenAPI responses کے بارے میں مزید معلومات { #more-information-about-openapi-responses } |
||||
|
|
||||
|
یہ دیکھنے کے لیے کہ آپ responses میں بالکل کیا شامل کر سکتے ہیں، آپ OpenAPI specification میں یہ حصے دیکھ سکتے ہیں: |
||||
|
|
||||
|
* [OpenAPI Responses Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responses-object)، اس میں `Response Object` شامل ہے۔ |
||||
|
* [OpenAPI Response Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#response-object)، آپ اپنے `responses` parameter کے اندر ہر response میں اس سے کچھ بھی براہ راست شامل کر سکتے ہیں۔ بشمول `description`، `headers`، `content` (اس کے اندر آپ مختلف media types اور JSON Schemas کا اعلان کرتے ہیں)، اور `links`۔ |
||||
@ -0,0 +1,41 @@ |
|||||
|
# اضافی Status Codes { #additional-status-codes } |
||||
|
|
||||
|
پہلے سے طے شدہ طور پر، **FastAPI** responses کو `JSONResponse` استعمال کر کے واپس کرے گا، آپ کے *path operation* سے واپس آنے والے مواد کو اس `JSONResponse` میں ڈال کر۔ |
||||
|
|
||||
|
یہ پہلے سے طے شدہ status code یا وہ استعمال کرے گا جو آپ نے اپنے *path operation* میں مقرر کیا ہے۔ |
||||
|
|
||||
|
## اضافی status codes { #additional-status-codes_1 } |
||||
|
|
||||
|
اگر آپ بنیادی status code کے علاوہ اضافی status codes واپس کرنا چاہتے ہیں، تو آپ براہ راست `Response` واپس کر کے ایسا کر سکتے ہیں، جیسے `JSONResponse`، اور اضافی status code براہ راست مقرر کر سکتے ہیں۔ |
||||
|
|
||||
|
مثال کے طور پر، فرض کریں کہ آپ ایک *path operation* چاہتے ہیں جو آئٹمز کو اپ ڈیٹ کرنے کی اجازت دے، اور کامیاب ہونے پر HTTP status code 200 "OK" واپس کرے۔ |
||||
|
|
||||
|
لیکن آپ یہ بھی چاہتے ہیں کہ یہ نئے آئٹمز قبول کرے۔ اور جب آئٹمز پہلے سے موجود نہیں تھے، تو یہ انہیں بنائے اور HTTP status code 201 "Created" واپس کرے۔ |
||||
|
|
||||
|
اس کے لیے، `JSONResponse` import کریں، اور اپنا مواد وہاں براہ راست واپس کریں، جو `status_code` آپ چاہتے ہیں وہ مقرر کرتے ہوئے: |
||||
|
|
||||
|
{* ../../docs_src/additional_status_codes/tutorial001_an_py310.py hl[4,25] *} |
||||
|
|
||||
|
/// warning | انتباہ |
||||
|
|
||||
|
جب آپ براہ راست `Response` واپس کرتے ہیں، جیسا کہ اوپر کی مثال میں، تو یہ براہ راست واپس کیا جائے گا۔ |
||||
|
|
||||
|
اسے model وغیرہ کے ساتھ serialize نہیں کیا جائے گا۔ |
||||
|
|
||||
|
یقینی بنائیں کہ اس میں وہ ڈیٹا ہے جو آپ چاہتے ہیں، اور قدریں درست JSON ہیں (اگر آپ `JSONResponse` استعمال کر رہے ہیں)۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
آپ `from starlette.responses import JSONResponse` بھی استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
**FastAPI** وہی `starlette.responses` فراہم کرتا ہے جو `fastapi.responses` کے طور پر، بس آپ یعنی developer کی سہولت کے لیے۔ لیکن زیادہ تر دستیاب responses براہ راست Starlette سے آتے ہیں۔ `status` کے ساتھ بھی یہی ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## OpenAPI اور API docs { #openapi-and-api-docs } |
||||
|
|
||||
|
اگر آپ اضافی status codes اور responses براہ راست واپس کرتے ہیں، تو وہ OpenAPI schema (API docs) میں شامل نہیں ہوں گے، کیونکہ FastAPI کے پاس پہلے سے یہ جاننے کا کوئی طریقہ نہیں ہے کہ آپ کیا واپس کرنے والے ہیں۔ |
||||
|
|
||||
|
لیکن آپ اپنے کوڈ میں اسے دستاویزی شکل دے سکتے ہیں، استعمال کرتے ہوئے: [OpenAPI میں اضافی Responses](additional-responses.md)۔ |
||||
@ -0,0 +1,163 @@ |
|||||
|
# ایڈوانسڈ Dependencies { #advanced-dependencies } |
||||
|
|
||||
|
## پیرامیٹرائزڈ dependencies { #parameterized-dependencies } |
||||
|
|
||||
|
ہم نے اب تک جتنی بھی dependencies دیکھی ہیں وہ ایک مقررہ function یا class ہیں۔ |
||||
|
|
||||
|
لیکن ایسے مواقع ہو سکتے ہیں جہاں آپ dependency پر parameters سیٹ کرنا چاہیں، بغیر بہت سے مختلف functions یا classes بنائے۔ |
||||
|
|
||||
|
آئیے تصور کریں کہ ہم ایک ایسی dependency چاہتے ہیں جو چیک کرے کہ query parameter `q` میں کوئی مقررہ مواد موجود ہے یا نہیں۔ |
||||
|
|
||||
|
لیکن ہم اس مقررہ مواد کو پیرامیٹرائز کرنا چاہتے ہیں۔ |
||||
|
|
||||
|
## ایک "callable" instance { #a-callable-instance } |
||||
|
|
||||
|
Python میں کسی class کے instance کو "callable" بنانے کا ایک طریقہ ہے۔ |
||||
|
|
||||
|
خود class نہیں (جو پہلے سے ہی callable ہے)، بلکہ اس class کا ایک instance۔ |
||||
|
|
||||
|
اس کے لیے ہم `__call__` method بیان کرتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[12] *} |
||||
|
|
||||
|
اس صورت میں، یہ `__call__` وہ ہے جسے **FastAPI** اضافی parameters اور sub-dependencies چیک کرنے کے لیے استعمال کرے گا، اور بعد میں آپ کے *path operation function* میں parameter کو قدر دینے کے لیے یہی call کیا جائے گا۔ |
||||
|
|
||||
|
## Instance کو پیرامیٹرائز کریں { #parameterize-the-instance } |
||||
|
|
||||
|
اب ہم `__init__` استعمال کر کے instance کے parameters بیان کر سکتے ہیں جنہیں ہم dependency کو "پیرامیٹرائز" کرنے کے لیے استعمال کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[9] *} |
||||
|
|
||||
|
اس صورت میں، **FastAPI** کبھی `__init__` کو چھوئے گا نہ اس کی فکر کرے گا، ہم اسے براہ راست اپنے کوڈ میں استعمال کریں گے۔ |
||||
|
|
||||
|
## ایک instance بنائیں { #create-an-instance } |
||||
|
|
||||
|
ہم اس class کا ایک instance اس طرح بنا سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[18] *} |
||||
|
|
||||
|
اور اس طرح ہم اپنی dependency کو "پیرامیٹرائز" کر سکتے ہیں، جس میں اب `"bar"` موجود ہے، بطور attribute `checker.fixed_content`۔ |
||||
|
|
||||
|
## Instance کو dependency کے طور پر استعمال کریں { #use-the-instance-as-a-dependency } |
||||
|
|
||||
|
پھر ہم اس `checker` کو `Depends(checker)` میں استعمال کر سکتے ہیں، `Depends(FixedContentQueryChecker)` کی بجائے، کیونکہ dependency خود instance ہے، `checker`، نہ کہ class۔ |
||||
|
|
||||
|
اور dependency حل کرتے وقت، **FastAPI** اس `checker` کو اس طرح call کرے گا: |
||||
|
|
||||
|
```Python |
||||
|
checker(q="somequery") |
||||
|
``` |
||||
|
|
||||
|
...اور جو بھی یہ واپس کرے اسے ہمارے *path operation function* میں dependency کی قدر کے طور پر parameter `fixed_content_included` میں دے گا: |
||||
|
|
||||
|
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[22] *} |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
یہ سب کچھ پیچیدہ لگ سکتا ہے۔ اور ابھی شاید یہ واضح نہ ہو کہ یہ کتنا مفید ہے۔ |
||||
|
|
||||
|
یہ مثالیں جان بوجھ کر سادہ ہیں، لیکن دکھاتی ہیں کہ یہ سب کیسے کام کرتا ہے۔ |
||||
|
|
||||
|
Security کے ابواب میں، ایسے utility functions ہیں جو بالکل اسی طرح بنائے گئے ہیں۔ |
||||
|
|
||||
|
اگر آپ نے یہ سب سمجھ لیا، تو آپ پہلے سے جانتے ہیں کہ security کے لیے وہ utility tools اندرونی طور پر کیسے کام کرتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## `yield`، `HTTPException`، `except` اور Background Tasks کے ساتھ Dependencies { #dependencies-with-yield-httpexception-except-and-background-tasks } |
||||
|
|
||||
|
/// warning | انتباہ |
||||
|
|
||||
|
آپ کو شاید ان تکنیکی تفصیلات کی ضرورت نہیں ہے۔ |
||||
|
|
||||
|
یہ تفصیلات بنیادی طور پر اس وقت مفید ہیں جب آپ کی FastAPI ایپلیکیشن 0.121.0 سے پرانی ہو اور آپ کو `yield` والی dependencies کے ساتھ مسائل درپیش ہوں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
`yield` والی Dependencies وقت کے ساتھ مختلف استعمال کے مواقع کے لیے اور کچھ مسائل حل کرنے کے لیے بدلتی رہی ہیں، یہاں تبدیلیوں کا خلاصہ ہے۔ |
||||
|
|
||||
|
### `yield` اور `scope` والی Dependencies { #dependencies-with-yield-and-scope } |
||||
|
|
||||
|
ورژن 0.121.0 میں، FastAPI نے `yield` والی dependencies کے لیے `Depends(scope="function")` کی سہولت شامل کی۔ |
||||
|
|
||||
|
`Depends(scope="function")` استعمال کرنے سے، `yield` کے بعد والا exit کوڈ *path operation function* ختم ہونے کے فوراً بعد چلتا ہے، response کلائنٹ کو واپس بھیجنے سے پہلے۔ |
||||
|
|
||||
|
اور `Depends(scope="request")` (جو کہ default ہے) استعمال کرنے سے، `yield` کے بعد والا exit کوڈ response بھیجنے کے بعد چلتا ہے۔ |
||||
|
|
||||
|
آپ اس کے بارے میں مزید [Dependencies with `yield` - Early exit and `scope`](../tutorial/dependencies/dependencies-with-yield.md#early-exit-and-scope) کی دستاویزات میں پڑھ سکتے ہیں۔ |
||||
|
|
||||
|
### `yield` اور `StreamingResponse` والی Dependencies، تکنیکی تفصیلات { #dependencies-with-yield-and-streamingresponse-technical-details } |
||||
|
|
||||
|
FastAPI 0.118.0 سے پہلے، اگر آپ `yield` والی dependency استعمال کرتے، تو exit کوڈ *path operation function* کے واپس آنے کے بعد لیکن response بھیجنے سے پہلے چلتا تھا۔ |
||||
|
|
||||
|
اس کا مقصد وسائل کو ضرورت سے زیادہ دیر تک نہ رکھنا تھا، response کے نیٹ ورک پر سفر کرنے کا انتظار کرتے ہوئے۔ |
||||
|
|
||||
|
اس تبدیلی کا یہ بھی مطلب تھا کہ اگر آپ `StreamingResponse` واپس کرتے، تو `yield` والی dependency کا exit کوڈ پہلے ہی چل چکا ہوتا۔ |
||||
|
|
||||
|
مثال کے طور پر، اگر آپ کے پاس `yield` والی dependency میں database session ہو، تو `StreamingResponse` ڈیٹا stream کرتے وقت اس session کو استعمال نہیں کر سکتا کیونکہ `yield` کے بعد exit کوڈ میں session پہلے ہی بند ہو چکا ہوتا۔ |
||||
|
|
||||
|
یہ رویہ 0.118.0 میں واپس بدل دیا گیا، تاکہ `yield` کے بعد والا exit کوڈ response بھیجنے کے بعد چلے۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
جیسا کہ آپ نیچے دیکھیں گے، یہ ورژن 0.106.0 سے پہلے کے رویے سے بہت ملتا جلتا ہے، لیکن کئی بہتریوں اور خاص صورتوں میں bug fixes کے ساتھ۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
#### ابتدائی Exit کوڈ کے ساتھ استعمال کے مواقع { #use-cases-with-early-exit-code } |
||||
|
|
||||
|
کچھ مخصوص شرائط کے ساتھ استعمال کے مواقع ہیں جو `yield` والی dependencies کے exit کوڈ کو response بھیجنے سے پہلے چلانے کے پرانے رویے سے فائدہ اٹھا سکتے ہیں۔ |
||||
|
|
||||
|
مثال کے طور پر، تصور کریں کہ آپ کے پاس ایسا کوڈ ہے جو `yield` والی dependency میں database session صرف صارف کی تصدیق کے لیے استعمال کرتا ہے، لیکن database session کبھی *path operation function* میں دوبارہ استعمال نہیں ہوتا، صرف dependency میں، **اور** response بھیجنے میں بہت وقت لگتا ہے، جیسے `StreamingResponse` جو آہستہ آہستہ ڈیٹا بھیجتا ہے، لیکن کسی وجہ سے database استعمال نہیں کرتا۔ |
||||
|
|
||||
|
اس صورت میں، database session response مکمل ہونے تک رکھا جائے گا، لیکن اگر آپ اسے استعمال نہیں کرتے، تو اسے رکھنا ضروری نہیں ہوگا۔ |
||||
|
|
||||
|
یہ کچھ اس طرح نظر آ سکتا ہے: |
||||
|
|
||||
|
{* ../../docs_src/dependencies/tutorial013_an_py310.py *} |
||||
|
|
||||
|
Exit کوڈ، `Session` کی خودکار بندش: |
||||
|
|
||||
|
{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[19:21] *} |
||||
|
|
||||
|
...سست ڈیٹا بھیجنے کے بعد response مکمل ہونے پر چلے گا: |
||||
|
|
||||
|
{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[30:38] hl[31:33] *} |
||||
|
|
||||
|
لیکن چونکہ `generate_stream()` database session استعمال نہیں کرتا، اس لیے response بھیجتے وقت session کھلا رکھنا واقعی ضروری نہیں ہے۔ |
||||
|
|
||||
|
اگر آپ کے پاس SQLModel (یا SQLAlchemy) استعمال کرنے والا یہ مخصوص معاملہ ہے، تو آپ ضرورت نہ رہنے پر session کو واضح طور پر بند کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/dependencies/tutorial014_an_py310.py ln[24:28] hl[28] *} |
||||
|
|
||||
|
اس طرح session database connection چھوڑ دے گا، تاکہ دوسری requests اسے استعمال کر سکیں۔ |
||||
|
|
||||
|
اگر آپ کے پاس کوئی مختلف استعمال کا موقع ہے جس میں `yield` والی dependency سے جلد باہر نکلنے کی ضرورت ہو، تو براہ کرم اپنے مخصوص استعمال کے ساتھ ایک [GitHub Discussion Question](https://github.com/fastapi/fastapi/discussions/new?category=questions) بنائیں اور بتائیں کہ آپ کو `yield` والی dependencies کے لیے جلد بند ہونے سے کیا فائدہ ہوگا۔ |
||||
|
|
||||
|
اگر `yield` والی dependencies میں جلد بند ہونے کے لیے قابل ذکر استعمال کے مواقع ہوں، تو میں جلد بند ہونے کا اختیار دینے کا ایک نیا طریقہ شامل کرنے پر غور کروں گا۔ |
||||
|
|
||||
|
### `yield` اور `except` والی Dependencies، تکنیکی تفصیلات { #dependencies-with-yield-and-except-technical-details } |
||||
|
|
||||
|
FastAPI 0.110.0 سے پہلے، اگر آپ `yield` والی dependency استعمال کرتے، اور پھر اس dependency میں `except` سے کوئی exception پکڑتے، اور آپ exception دوبارہ raise نہیں کرتے تھے، تو exception خودکار طور پر کسی بھی exception handlers یا internal server error handler کو raise/forward کر دیا جاتا تھا۔ |
||||
|
|
||||
|
یہ ورژن 0.110.0 میں تبدیل کیا گیا تاکہ بغیر handler کے forward کیے گئے exceptions سے غیر منظم memory consumption (internal server errors) کو ٹھیک کیا جا سکے، اور اسے عام Python کوڈ کے رویے سے ہم آہنگ بنایا جا سکے۔ |
||||
|
|
||||
|
### Background Tasks اور `yield` والی Dependencies، تکنیکی تفصیلات { #background-tasks-and-dependencies-with-yield-technical-details } |
||||
|
|
||||
|
FastAPI 0.106.0 سے پہلے، `yield` کے بعد exceptions raise کرنا ممکن نہیں تھا، `yield` والی dependencies میں exit کوڈ response بھیجنے کے *بعد* چلتا تھا، اس لیے [Exception Handlers](../tutorial/handling-errors.md#install-custom-exception-handlers) پہلے ہی چل چکے ہوتے تھے۔ |
||||
|
|
||||
|
یہ بنیادی طور پر اس لیے ڈیزائن کیا گیا تھا تاکہ dependencies سے "yield" کیے گئے اشیاء کو background tasks کے اندر استعمال کیا جا سکے، کیونکہ exit کوڈ background tasks مکمل ہونے کے بعد چلتا تھا۔ |
||||
|
|
||||
|
یہ FastAPI 0.106.0 میں اس ارادے سے تبدیل کیا گیا کہ response کے نیٹ ورک پر سفر کرنے کا انتظار کرتے ہوئے وسائل کو نہ رکھا جائے۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
مزید برآں، ایک background task عام طور پر منطق کا ایک آزاد حصہ ہوتا ہے جسے الگ سے، اپنے وسائل کے ساتھ (مثلاً اپنا database connection) سنبھالا جانا چاہیے۔ |
||||
|
|
||||
|
اس طرح آپ کا کوڈ شاید زیادہ صاف ہوگا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
اگر آپ پہلے اس رویے پر انحصار کرتے تھے، تو اب آپ کو background task کے اندر ہی background tasks کے لیے وسائل بنانے چاہئیں، اور اندرونی طور پر صرف وہ ڈیٹا استعمال کرنا چاہیے جو `yield` والی dependencies کے وسائل پر منحصر نہ ہو۔ |
||||
|
|
||||
|
مثال کے طور پر، ایک ہی database session استعمال کرنے کی بجائے، آپ background task کے اندر ایک نیا database session بنائیں گے، اور اس نئے session سے database سے اشیاء حاصل کریں گے۔ اور پھر background task function کو parameter کے طور پر database سے آبجیکٹ دینے کی بجائے، آپ اس آبجیکٹ کی ID دیں گے اور پھر background task function کے اندر دوبارہ آبجیکٹ حاصل کریں گے۔ |
||||
@ -0,0 +1,61 @@ |
|||||
|
# ایڈوانسڈ Python Types { #advanced-python-types } |
||||
|
|
||||
|
یہاں کچھ اضافی خیالات ہیں جو Python types کے ساتھ کام کرتے وقت مفید ہو سکتے ہیں۔ |
||||
|
|
||||
|
## `Union` یا `Optional` کا استعمال { #using-union-or-optional } |
||||
|
|
||||
|
اگر آپ کا کوڈ کسی وجہ سے `|` استعمال نہیں کر سکتا، مثلاً اگر یہ type annotation میں نہیں بلکہ `response_model=` جیسی کسی چیز میں ہے، تو عمودی بار (`|`) استعمال کرنے کی بجائے آپ `typing` سے `Union` استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
مثال کے طور پر، آپ بیان کر سکتے ہیں کہ کچھ `str` یا `None` ہو سکتا ہے: |
||||
|
|
||||
|
```python |
||||
|
from typing import Union |
||||
|
|
||||
|
|
||||
|
def say_hi(name: Union[str, None]): |
||||
|
print(f"Hi {name}!") |
||||
|
``` |
||||
|
|
||||
|
`typing` میں `None` بیان کرنے کا ایک شارٹ کٹ بھی ہے، `Optional` کے ساتھ۔ |
||||
|
|
||||
|
یہاں میرے بہت **ذاتی** نقطہ نظر سے ایک مشورہ: |
||||
|
|
||||
|
* `Optional[SomeType]` استعمال کرنے سے بچیں |
||||
|
* اس کی بجائے **`Union[SomeType, None]`** استعمال کریں۔ |
||||
|
|
||||
|
دونوں ایک جیسے ہیں اور اندرونی طور پر وہی ہیں، لیکن میں `Optional` کی بجائے `Union` تجویز کروں گا کیونکہ لفظ "**optional**" یہ تاثر دے سکتا ہے کہ قدر اختیاری ہے، اور اس کا اصل مطلب ہے "یہ `None` ہو سکتا ہے"، چاہے یہ اختیاری نہ ہو اور پھر بھی ضروری ہو۔ |
||||
|
|
||||
|
مجھے لگتا ہے کہ `Union[SomeType, None]` زیادہ واضح طور پر بتاتا ہے کہ اس کا مطلب کیا ہے۔ |
||||
|
|
||||
|
یہ صرف الفاظ اور ناموں کے بارے میں ہے۔ لیکن یہ الفاظ اثر ڈال سکتے ہیں کہ آپ اور آپ کے ساتھی کوڈ کے بارے میں کیسے سوچتے ہیں۔ |
||||
|
|
||||
|
بطور مثال، یہ function لیں: |
||||
|
|
||||
|
```python |
||||
|
from typing import Optional |
||||
|
|
||||
|
|
||||
|
def say_hi(name: Optional[str]): |
||||
|
print(f"Hey {name}!") |
||||
|
``` |
||||
|
|
||||
|
parameter `name` کو `Optional[str]` بیان کیا گیا ہے، لیکن یہ **اختیاری نہیں** ہے، آپ function کو بغیر parameter کے نہیں بلا سکتے: |
||||
|
|
||||
|
```Python |
||||
|
say_hi() # اوہ نہیں، یہ غلطی دے گا! |
||||
|
``` |
||||
|
|
||||
|
`name` parameter پھر بھی **ضروری** ہے (نہ کہ *اختیاری*) کیونکہ اس کی ڈیفالٹ قدر نہیں ہے۔ پھر بھی، `name` قدر کے طور پر `None` قبول کرتا ہے: |
||||
|
|
||||
|
```Python |
||||
|
say_hi(name=None) # یہ کام کرتا ہے، None درست ہے |
||||
|
``` |
||||
|
|
||||
|
خوشخبری یہ ہے کہ زیادہ تر صورتوں میں، آپ آسانی سے types کی unions بیان کرنے کے لیے `|` استعمال کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
def say_hi(name: str | None): |
||||
|
print(f"Hey {name}!") |
||||
|
``` |
||||
|
|
||||
|
تو، عام طور پر آپ کو `Optional` اور `Union` جیسے ناموں کی فکر کرنے کی ضرورت نہیں ہے۔ |
||||
@ -0,0 +1,99 @@ |
|||||
|
# Async Tests { #async-tests } |
||||
|
|
||||
|
آپ پہلے ہی دیکھ چکے ہیں کہ فراہم کیے گئے `TestClient` کا استعمال کرتے ہوئے اپنی **FastAPI** ایپلیکیشنز کی جانچ کیسے کی جائے۔ اب تک آپ نے صرف synchronous ٹیسٹ لکھنا دیکھا ہے، بغیر `async` functions کے استعمال کے۔ |
||||
|
|
||||
|
اپنے ٹیسٹوں میں asynchronous functions استعمال کر سکنا مفید ہو سکتا ہے، مثال کے طور پر، جب آپ اپنے database سے asynchronously query کر رہے ہوں۔ تصور کریں کہ آپ اپنی FastAPI ایپلیکیشن کو requests بھیجنا چاہتے ہیں اور پھر تصدیق کرنا چاہتے ہیں کہ آپ کے backend نے database میں درست ڈیٹا لکھا ہے، ایک async database library استعمال کرتے ہوئے۔ |
||||
|
|
||||
|
آئیے دیکھتے ہیں کہ ہم یہ کیسے کر سکتے ہیں۔ |
||||
|
|
||||
|
## pytest.mark.anyio { #pytest-mark-anyio } |
||||
|
|
||||
|
اگر ہم اپنے ٹیسٹوں میں asynchronous functions call کرنا چاہتے ہیں، تو ہمارے test functions کو asynchronous ہونا ہوگا۔ AnyIO اس کے لیے ایک عمدہ plugin فراہم کرتا ہے، جو ہمیں یہ بتانے دیتا ہے کہ کچھ test functions asynchronously call کیے جائیں۔ |
||||
|
|
||||
|
## HTTPX { #httpx } |
||||
|
|
||||
|
اگر آپ کی **FastAPI** ایپلیکیشن `async def` کی بجائے عام `def` functions استعمال کرتی ہے، تب بھی یہ اندرونی طور پر ایک `async` ایپلیکیشن ہے۔ |
||||
|
|
||||
|
`TestClient` اندرونی طور پر کچھ خاص عمل کرتا ہے تاکہ آپ کے عام `def` test functions میں asynchronous FastAPI ایپلیکیشن کو call کیا جا سکے، معیاری pytest استعمال کرتے ہوئے۔ لیکن وہ خاص عمل asynchronous functions کے اندر استعمال ہونے پر مزید کام نہیں کرتا۔ اپنے ٹیسٹ asynchronously چلانے سے، ہم اپنے test functions کے اندر `TestClient` مزید استعمال نہیں کر سکتے۔ |
||||
|
|
||||
|
`TestClient` [HTTPX](https://www.python-httpx.org) پر مبنی ہے، اور خوش قسمتی سے، ہم اسے براہ راست API کی جانچ کے لیے استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
## مثال { #example } |
||||
|
|
||||
|
ایک سادہ مثال کے لیے، آئیے ایسا فائل ڈھانچہ لیتے ہیں جو [Bigger Applications](../tutorial/bigger-applications.md) اور [Testing](../tutorial/testing.md) میں بیان کیے گئے سے ملتا جلتا ہو: |
||||
|
|
||||
|
``` |
||||
|
. |
||||
|
├── app |
||||
|
│ ├── __init__.py |
||||
|
│ ├── main.py |
||||
|
│ └── test_main.py |
||||
|
``` |
||||
|
|
||||
|
`main.py` فائل میں ہوگا: |
||||
|
|
||||
|
{* ../../docs_src/async_tests/app_a_py310/main.py *} |
||||
|
|
||||
|
`test_main.py` فائل میں `main.py` کے ٹیسٹ ہوں گے، یہ اب کچھ اس طرح نظر آ سکتی ہے: |
||||
|
|
||||
|
{* ../../docs_src/async_tests/app_a_py310/test_main.py *} |
||||
|
|
||||
|
## اسے چلائیں { #run-it } |
||||
|
|
||||
|
آپ اپنے ٹیسٹ حسب معمول اس طرح چلا سکتے ہیں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ pytest |
||||
|
|
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
## تفصیل سے { #in-detail } |
||||
|
|
||||
|
`@pytest.mark.anyio` marker pytest کو بتاتا ہے کہ یہ test function asynchronously call کیا جانا چاہیے: |
||||
|
|
||||
|
{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[7] *} |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
نوٹ کریں کہ test function اب `async def` ہے نہ کہ پہلے کی طرح صرف `def` جب `TestClient` استعمال ہوتا تھا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
پھر ہم app کے ساتھ ایک `AsyncClient` بنا سکتے ہیں، اور `await` استعمال کرتے ہوئے اسے async requests بھیج سکتے ہیں۔ |
||||
|
|
||||
|
{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[9:12] *} |
||||
|
|
||||
|
یہ اس کے مساوی ہے: |
||||
|
|
||||
|
```Python |
||||
|
response = client.get('/') |
||||
|
``` |
||||
|
|
||||
|
...جو ہم `TestClient` کے ساتھ اپنی requests بنانے کے لیے استعمال کرتے تھے۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
نوٹ کریں کہ ہم نئے `AsyncClient` کے ساتھ async/await استعمال کر رہے ہیں - request asynchronous ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// warning | انتباہ |
||||
|
|
||||
|
اگر آپ کی ایپلیکیشن lifespan events پر انحصار کرتی ہے، تو `AsyncClient` ان events کو trigger نہیں کرے گا۔ ان کو trigger ہونا یقینی بنانے کے لیے، [florimondmanca/asgi-lifespan](https://github.com/florimondmanca/asgi-lifespan#usage) سے `LifespanManager` استعمال کریں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## دیگر Asynchronous Function Calls { #other-asynchronous-function-calls } |
||||
|
|
||||
|
چونکہ testing function اب asynchronous ہے، آپ اب اپنی FastAPI ایپلیکیشن کو requests بھیجنے کے علاوہ دیگر `async` functions بھی call (اور `await`) کر سکتے ہیں، بالکل اسی طرح جیسے آپ انہیں اپنے کوڈ میں کہیں بھی call کرتے۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
اگر آپ کو اپنے ٹیسٹوں میں asynchronous function calls integrate کرتے وقت `RuntimeError: Task attached to a different loop` آئے (مثلاً [MongoDB کا MotorClient](https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop) استعمال کرتے وقت)، تو یاد رکھیں کہ event loop کی ضرورت رکھنے والے objects صرف async functions کے اندر بنائیں، مثلاً `@app.on_event("startup")` callback۔ |
||||
|
|
||||
|
/// |
||||
@ -0,0 +1,466 @@ |
|||||
|
# Proxy کے پیچھے { #behind-a-proxy } |
||||
|
|
||||
|
بہت سے حالات میں، آپ اپنی FastAPI ایپ کے سامنے **Traefik** یا **Nginx** جیسا **proxy** استعمال کریں گے۔ |
||||
|
|
||||
|
یہ proxy HTTPS سرٹیفکیٹ اور دیگر چیزیں ہینڈل کر سکتے ہیں۔ |
||||
|
|
||||
|
## Proxy Forwarded Headers { #proxy-forwarded-headers } |
||||
|
|
||||
|
آپ کی ایپلیکیشن کے سامنے موجود **proxy** عام طور پر requests کو آپ کے **server** تک بھیجنے سے پہلے کچھ headers شامل کرتا ہے تاکہ server کو معلوم ہو کہ request proxy سے **forward** کی گئی ہے، اور اسے اصل (عوامی) URL، domain، اور HTTPS استعمال ہونے وغیرہ کی معلومات مل سکیں۔ |
||||
|
|
||||
|
**server** پروگرام (مثال کے طور پر **Uvicorn** بذریعہ **FastAPI CLI**) ان headers کو سمجھنے اور پھر وہ معلومات آپ کی ایپلیکیشن کو فراہم کرنے کے قابل ہے۔ |
||||
|
|
||||
|
لیکن سیکیورٹی کی وجہ سے، چونکہ server کو معلوم نہیں کہ وہ کسی قابل اعتماد proxy کے پیچھے ہے، یہ ان headers کو نہیں پڑھے گا۔ |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
proxy headers یہ ہیں: |
||||
|
|
||||
|
* [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For) |
||||
|
* [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto) |
||||
|
* [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host) |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### Proxy Forwarded Headers کو فعال کرنا { #enable-proxy-forwarded-headers } |
||||
|
|
||||
|
آپ FastAPI CLI کو *CLI Option* `--forwarded-allow-ips` کے ساتھ شروع کر سکتے ہیں اور ان IP addresses کو پاس کر سکتے ہیں جن پر forwarded headers پڑھنے کے لیے بھروسہ کرنا ہے۔ |
||||
|
|
||||
|
اگر آپ اسے `--forwarded-allow-ips="*"` پر سیٹ کریں تو یہ تمام آنے والے IPs پر بھروسہ کرے گا۔ |
||||
|
|
||||
|
اگر آپ کا **server** کسی قابل اعتماد **proxy** کے پیچھے ہے اور صرف proxy ہی اس سے بات کرتا ہے، تو یہ اس **proxy** کے IP کو قبول کر لے گا۔ |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ fastapi run --forwarded-allow-ips="*" |
||||
|
|
||||
|
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
### HTTPS کے ساتھ Redirects { #redirects-with-https } |
||||
|
|
||||
|
مثال کے طور پر، فرض کریں آپ ایک *path operation* `/items/` بناتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/behind_a_proxy/tutorial001_01_py310.py hl[6] *} |
||||
|
|
||||
|
اگر client `/items` پر جانے کی کوشش کرے تو بطور ڈیفالٹ اسے `/items/` کی طرف redirect کیا جائے گا۔ |
||||
|
|
||||
|
لیکن `--forwarded-allow-ips` *CLI Option* سیٹ کرنے سے پہلے یہ `http://localhost:8000/items/` کی طرف redirect کر سکتا تھا۔ |
||||
|
|
||||
|
لیکن شاید آپ کی ایپلیکیشن `https://mysuperapp.com` پر ہوسٹ ہے، اور redirect `https://mysuperapp.com/items/` کی طرف ہونا چاہیے۔ |
||||
|
|
||||
|
`--proxy-headers` سیٹ کرنے کے بعد اب FastAPI درست جگہ پر redirect کر سکے گا۔ |
||||
|
|
||||
|
``` |
||||
|
https://mysuperapp.com/items/ |
||||
|
``` |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
اگر آپ HTTPS کے بارے میں مزید جاننا چاہتے ہیں تو [HTTPS کے بارے میں](../deployment/https.md) گائیڈ دیکھیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### Proxy Forwarded Headers کیسے کام کرتے ہیں { #how-proxy-forwarded-headers-work } |
||||
|
|
||||
|
یہاں ایک بصری نمائندگی ہے کہ **proxy** client اور **application server** کے درمیان forwarded headers کیسے شامل کرتا ہے: |
||||
|
|
||||
|
```mermaid |
||||
|
sequenceDiagram |
||||
|
participant Client |
||||
|
participant Proxy as Proxy/Load Balancer |
||||
|
participant Server as FastAPI Server |
||||
|
|
||||
|
Client->>Proxy: HTTPS Request<br/>Host: mysuperapp.com<br/>Path: /items |
||||
|
|
||||
|
Note over Proxy: Proxy adds forwarded headers |
||||
|
|
||||
|
Proxy->>Server: HTTP Request<br/>X-Forwarded-For: [client IP]<br/>X-Forwarded-Proto: https<br/>X-Forwarded-Host: mysuperapp.com<br/>Path: /items |
||||
|
|
||||
|
Note over Server: Server interprets headers<br/>(if --forwarded-allow-ips is set) |
||||
|
|
||||
|
Server->>Proxy: HTTP Response<br/>with correct HTTPS URLs |
||||
|
|
||||
|
Proxy->>Client: HTTPS Response |
||||
|
``` |
||||
|
|
||||
|
**proxy** اصل client request کو روکتا ہے اور خصوصی *forwarded* headers (`X-Forwarded-*`) شامل کرتا ہے اس سے پہلے کہ request **application server** کو بھیجے۔ |
||||
|
|
||||
|
یہ headers اصل request کی وہ معلومات محفوظ رکھتے ہیں جو بصورت دیگر ضائع ہو جاتیں: |
||||
|
|
||||
|
* **X-Forwarded-For**: اصل client کا IP address |
||||
|
* **X-Forwarded-Proto**: اصل protocol (`https`) |
||||
|
* **X-Forwarded-Host**: اصل host (`mysuperapp.com`) |
||||
|
|
||||
|
جب **FastAPI CLI** کو `--forwarded-allow-ips` کے ساتھ ترتیب دیا جائے تو یہ ان headers پر بھروسہ کرتا ہے اور انہیں استعمال کرتا ہے، مثلاً redirects میں درست URLs بنانے کے لیے۔ |
||||
|
|
||||
|
## ہٹائے گئے path prefix والا Proxy { #proxy-with-a-stripped-path-prefix } |
||||
|
|
||||
|
آپ کے پاس ایسا proxy ہو سکتا ہے جو آپ کی ایپلیکیشن میں path prefix شامل کرے۔ |
||||
|
|
||||
|
ان صورتوں میں آپ اپنی ایپلیکیشن کو ترتیب دینے کے لیے `root_path` استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
`root_path` ASGI specification کی فراہم کردہ ایک مکینزم ہے (جس پر FastAPI بنایا گیا ہے، Starlette کے ذریعے)۔ |
||||
|
|
||||
|
`root_path` ان مخصوص صورتوں کو ہینڈل کرنے کے لیے استعمال ہوتا ہے۔ |
||||
|
|
||||
|
اور اسے اندرونی طور پر sub-applications mount کرتے وقت بھی استعمال کیا جاتا ہے۔ |
||||
|
|
||||
|
ہٹائے گئے path prefix والے proxy کا مطلب ہے کہ آپ اپنے کوڈ میں `/app` پر path بیان کر سکتے ہیں، لیکن پھر آپ اوپر ایک تہہ شامل کرتے ہیں (proxy) جو آپ کی **FastAPI** ایپلیکیشن کو `/api/v1` جیسے path کے نیچے رکھے گا۔ |
||||
|
|
||||
|
اس صورت میں، اصل path `/app` دراصل `/api/v1/app` پر serve ہوگا۔ |
||||
|
|
||||
|
خواہ آپ کا سارا کوڈ یہ سمجھ کر لکھا گیا ہو کہ صرف `/app` ہے۔ |
||||
|
|
||||
|
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[6] *} |
||||
|
|
||||
|
اور proxy request کو app server (شاید Uvicorn بذریعہ FastAPI CLI) تک بھیجنے سے پہلے **"path prefix کو ہٹا"** رہا ہوگا، تاکہ آپ کی ایپلیکیشن یہ سمجھے کہ وہ `/app` پر serve ہو رہی ہے، اور آپ کو اپنے تمام کوڈ میں `/api/v1` prefix شامل کرنے کی ضرورت نہ ہو۔ |
||||
|
|
||||
|
یہاں تک سب کچھ عام طور پر کام کرے گا۔ |
||||
|
|
||||
|
لیکن پھر، جب آپ integrated docs UI (frontend) کھولیں گے، تو وہ OpenAPI schema `/openapi.json` سے لینے کی کوشش کرے گا، `/api/v1/openapi.json` سے نہیں۔ |
||||
|
|
||||
|
تو، frontend (جو browser میں چلتا ہے) `/openapi.json` تک پہنچنے کی کوشش کرے گا اور OpenAPI schema نہیں مل پائے گا۔ |
||||
|
|
||||
|
چونکہ ہمارے پاس ایپ کے لیے `/api/v1` path prefix والا proxy ہے، frontend کو OpenAPI schema `/api/v1/openapi.json` سے لینا ہوگا۔ |
||||
|
|
||||
|
```mermaid |
||||
|
graph LR |
||||
|
|
||||
|
browser("Browser") |
||||
|
proxy["Proxy on http://0.0.0.0:9999/api/v1/app"] |
||||
|
server["Server on http://127.0.0.1:8000/app"] |
||||
|
|
||||
|
browser --> proxy |
||||
|
proxy --> server |
||||
|
``` |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
IP `0.0.0.0` عام طور پر اس بات کی نشاندہی کرتا ہے کہ پروگرام اس مشین/server پر دستیاب تمام IPs پر سنتا ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
docs UI کو یہ بھی ضرورت ہوگی کہ OpenAPI schema یہ بتائے کہ یہ API `server` `/api/v1` پر واقع ہے (proxy کے پیچھے)۔ مثال کے طور پر: |
||||
|
|
||||
|
```JSON hl_lines="4-8" |
||||
|
{ |
||||
|
"openapi": "3.1.0", |
||||
|
// More stuff here |
||||
|
"servers": [ |
||||
|
{ |
||||
|
"url": "/api/v1" |
||||
|
} |
||||
|
], |
||||
|
"paths": { |
||||
|
// More stuff here |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
اس مثال میں، "Proxy" کچھ **Traefik** جیسا ہو سکتا ہے۔ اور server کچھ FastAPI CLI بمع **Uvicorn** جیسا ہو سکتا ہے، جو آپ کی FastAPI ایپلیکیشن چلا رہا ہو۔ |
||||
|
|
||||
|
### `root_path` فراہم کرنا { #providing-the-root-path } |
||||
|
|
||||
|
یہ حاصل کرنے کے لیے، آپ command line option `--root-path` اس طرح استعمال کر سکتے ہیں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1 |
||||
|
|
||||
|
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
اگر آپ Hypercorn استعمال کرتے ہیں تو اس میں بھی `--root-path` آپشن ہے۔ |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
ASGI specification اس استعمال کے لیے `root_path` بیان کرتا ہے۔ |
||||
|
|
||||
|
اور `--root-path` command line option وہ `root_path` فراہم کرتا ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### موجودہ `root_path` چیک کرنا { #checking-the-current-root-path } |
||||
|
|
||||
|
آپ ہر request کے لیے اپنی ایپلیکیشن کا استعمال شدہ موجودہ `root_path` حاصل کر سکتے ہیں، یہ `scope` dictionary کا حصہ ہے (جو ASGI spec کا حصہ ہے)۔ |
||||
|
|
||||
|
یہاں ہم اسے صرف مظاہرے کے مقاصد کے لیے پیغام میں شامل کر رہے ہیں۔ |
||||
|
|
||||
|
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[8] *} |
||||
|
|
||||
|
پھر، اگر آپ Uvicorn اس طرح شروع کریں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1 |
||||
|
|
||||
|
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
response کچھ اس طرح ہوگا: |
||||
|
|
||||
|
```JSON |
||||
|
{ |
||||
|
"message": "Hello World", |
||||
|
"root_path": "/api/v1" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
### FastAPI ایپ میں `root_path` سیٹ کرنا { #setting-the-root-path-in-the-fastapi-app } |
||||
|
|
||||
|
متبادل طور پر، اگر آپ کے پاس `--root-path` جیسا command line option فراہم کرنے کا کوئی طریقہ نہیں ہے، تو آپ اپنی FastAPI ایپ بناتے وقت `root_path` parameter سیٹ کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/behind_a_proxy/tutorial002_py310.py hl[3] *} |
||||
|
|
||||
|
`FastAPI` کو `root_path` پاس کرنا Uvicorn یا Hypercorn کو `--root-path` command line option پاس کرنے کے برابر ہے۔ |
||||
|
|
||||
|
### `root_path` کے بارے میں { #about-root-path } |
||||
|
|
||||
|
یاد رکھیں کہ server (Uvicorn) اس `root_path` کو ایپ کو پاس کرنے کے علاوہ کسی اور چیز کے لیے استعمال نہیں کرے گا۔ |
||||
|
|
||||
|
لیکن اگر آپ اپنے browser سے [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app) پر جائیں تو آپ کو عام response نظر آئے گا: |
||||
|
|
||||
|
```JSON |
||||
|
{ |
||||
|
"message": "Hello World", |
||||
|
"root_path": "/api/v1" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
تو، یہ `http://127.0.0.1:8000/api/v1/app` پر رسائی کی توقع نہیں رکھے گا۔ |
||||
|
|
||||
|
Uvicorn توقع رکھے گا کہ proxy، Uvicorn تک `http://127.0.0.1:8000/app` پر رسائی کرے، اور پھر اوپر اضافی `/api/v1` prefix شامل کرنا proxy کی ذمہ داری ہوگی۔ |
||||
|
|
||||
|
## ہٹائے گئے path prefix والے proxy کے بارے میں { #about-proxies-with-a-stripped-path-prefix } |
||||
|
|
||||
|
یاد رکھیں کہ ہٹائے گئے path prefix والا proxy اسے ترتیب دینے کے طریقوں میں سے صرف ایک ہے۔ |
||||
|
|
||||
|
شاید بہت سے معاملات میں ڈیفالٹ یہ ہوگا کہ proxy کے پاس ہٹایا گیا path prefix نہیں ہوگا۔ |
||||
|
|
||||
|
ایسی صورت میں (بغیر ہٹائے گئے path prefix کے)، proxy کچھ ایسے `https://myawesomeapp.com` پر سنے گا، اور پھر اگر browser `https://myawesomeapp.com/api/v1/app` پر جائے اور آپ کا server (مثلاً Uvicorn) `http://127.0.0.1:8000` پر سنتا ہو تو proxy (بغیر ہٹائے گئے path prefix کے) Uvicorn تک اسی path پر رسائی کرے گا: `http://127.0.0.1:8000/api/v1/app`۔ |
||||
|
|
||||
|
## Traefik کے ساتھ مقامی جانچ { #testing-locally-with-traefik } |
||||
|
|
||||
|
آپ [Traefik](https://docs.traefik.io/) استعمال کرتے ہوئے ہٹائے گئے path prefix کے ساتھ آسانی سے مقامی طور پر تجربہ کر سکتے ہیں۔ |
||||
|
|
||||
|
[Traefik ڈاؤن لوڈ کریں](https://github.com/containous/traefik/releases)، یہ ایک واحد binary ہے، آپ compressed فائل نکال کر اسے براہ راست terminal سے چلا سکتے ہیں۔ |
||||
|
|
||||
|
پھر ایک فائل `traefik.toml` بنائیں جس میں یہ ہو: |
||||
|
|
||||
|
```TOML hl_lines="3" |
||||
|
[entryPoints] |
||||
|
[entryPoints.http] |
||||
|
address = ":9999" |
||||
|
|
||||
|
[providers] |
||||
|
[providers.file] |
||||
|
filename = "routes.toml" |
||||
|
``` |
||||
|
|
||||
|
یہ Traefik کو بتاتا ہے کہ port 9999 پر سنے اور ایک اور فائل `routes.toml` استعمال کرے۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
ہم معیاری HTTP port 80 کی بجائے port 9999 استعمال کر رہے ہیں تاکہ آپ کو اسے admin (`sudo`) مراعات کے ساتھ چلانے کی ضرورت نہ ہو۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
اب وہ دوسری فائل `routes.toml` بنائیں: |
||||
|
|
||||
|
```TOML hl_lines="5 12 20" |
||||
|
[http] |
||||
|
[http.middlewares] |
||||
|
|
||||
|
[http.middlewares.api-stripprefix.stripPrefix] |
||||
|
prefixes = ["/api/v1"] |
||||
|
|
||||
|
[http.routers] |
||||
|
|
||||
|
[http.routers.app-http] |
||||
|
entryPoints = ["http"] |
||||
|
service = "app" |
||||
|
rule = "PathPrefix(`/api/v1`)" |
||||
|
middlewares = ["api-stripprefix"] |
||||
|
|
||||
|
[http.services] |
||||
|
|
||||
|
[http.services.app] |
||||
|
[http.services.app.loadBalancer] |
||||
|
[[http.services.app.loadBalancer.servers]] |
||||
|
url = "http://127.0.0.1:8000" |
||||
|
``` |
||||
|
|
||||
|
یہ فائل Traefik کو path prefix `/api/v1` استعمال کرنے کے لیے ترتیب دیتی ہے۔ |
||||
|
|
||||
|
اور پھر Traefik اپنی requests `http://127.0.0.1:8000` پر چلنے والے آپ کے Uvicorn کو redirect کرے گا۔ |
||||
|
|
||||
|
اب Traefik شروع کریں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ ./traefik --configFile=traefik.toml |
||||
|
|
||||
|
INFO[0000] Configuration loaded from file: /home/user/awesomeapi/traefik.toml |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
اور اب `--root-path` آپشن کے ساتھ اپنی ایپ شروع کریں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1 |
||||
|
|
||||
|
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
### Responses چیک کریں { #check-the-responses } |
||||
|
|
||||
|
اب، اگر آپ Uvicorn کے port والے URL پر جائیں: [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app)، تو آپ کو عام response نظر آئے گا: |
||||
|
|
||||
|
```JSON |
||||
|
{ |
||||
|
"message": "Hello World", |
||||
|
"root_path": "/api/v1" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
غور کریں کہ باوجود اس کے کہ آپ `http://127.0.0.1:8000/app` پر رسائی کر رہے ہیں، یہ `/api/v1` کا `root_path` دکھاتا ہے، جو `--root-path` آپشن سے لیا گیا ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
اور اب path prefix سمیت Traefik کے port والا URL کھولیں: [http://127.0.0.1:9999/api/v1/app](http://127.0.0.1:9999/api/v1/app)۔ |
||||
|
|
||||
|
ہمیں وہی response ملتا ہے: |
||||
|
|
||||
|
```JSON |
||||
|
{ |
||||
|
"message": "Hello World", |
||||
|
"root_path": "/api/v1" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
لیکن اس بار proxy کے فراہم کردہ prefix path والے URL پر: `/api/v1`۔ |
||||
|
|
||||
|
ظاہر ہے، یہاں خیال یہ ہے کہ ہر کوئی ایپ تک proxy کے ذریعے رسائی کرے، تو path prefix `/api/v1` والا ورژن "درست" ہے۔ |
||||
|
|
||||
|
اور بغیر path prefix کا ورژن (`http://127.0.0.1:8000/app`)، جو Uvicorn براہ راست فراہم کرتا ہے، خصوصی طور پر _proxy_ (Traefik) کے لیے ہے تاکہ وہ اس تک رسائی کرے۔ |
||||
|
|
||||
|
یہ ظاہر کرتا ہے کہ Proxy (Traefik) path prefix کیسے استعمال کرتا ہے اور server (Uvicorn) `--root-path` آپشن سے `root_path` کیسے استعمال کرتا ہے۔ |
||||
|
|
||||
|
### Docs UI چیک کریں { #check-the-docs-ui } |
||||
|
|
||||
|
لیکن یہاں دلچسپ حصہ ہے۔ |
||||
|
|
||||
|
ایپ تک رسائی کا "سرکاری" طریقہ اس path prefix والے proxy کے ذریعے ہے جو ہم نے بیان کیا۔ تو، جیسا کہ ہم توقع کریں گے، اگر آپ Uvicorn کے براہ راست فراہم کردہ docs UI کو آزمائیں، بغیر URL میں path prefix کے، تو یہ کام نہیں کرے گا، کیونکہ اسے proxy کے ذریعے رسائی کی توقع ہے۔ |
||||
|
|
||||
|
آپ اسے [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) پر چیک کر سکتے ہیں: |
||||
|
|
||||
|
<img src="/img/tutorial/behind-a-proxy/image01.png"> |
||||
|
|
||||
|
لیکن اگر ہم "سرکاری" URL سے proxy کے ذریعے port `9999` پر docs UI رسائی کریں، `/api/v1/docs` پر، تو یہ درست طریقے سے کام کرتا ہے! |
||||
|
|
||||
|
آپ اسے [http://127.0.0.1:9999/api/v1/docs](http://127.0.0.1:9999/api/v1/docs) پر چیک کر سکتے ہیں: |
||||
|
|
||||
|
<img src="/img/tutorial/behind-a-proxy/image02.png"> |
||||
|
|
||||
|
بالکل جیسا ہم چاہتے تھے۔ |
||||
|
|
||||
|
اس کی وجہ یہ ہے کہ FastAPI اس `root_path` کو استعمال کرکے OpenAPI میں `root_path` کے فراہم کردہ URL کے ساتھ ڈیفالٹ `server` بناتا ہے۔ |
||||
|
|
||||
|
## اضافی servers { #additional-servers } |
||||
|
|
||||
|
/// warning | انتباہ |
||||
|
|
||||
|
یہ ایک زیادہ ایڈوانسڈ استعمال ہے۔ اسے چھوڑ دینے میں کوئی حرج نہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
بطور ڈیفالٹ، **FastAPI** OpenAPI schema میں `root_path` کے URL کے ساتھ ایک `server` بنائے گا۔ |
||||
|
|
||||
|
لیکن آپ دیگر متبادل `servers` بھی فراہم کر سکتے ہیں، مثال کے طور پر اگر آپ چاہتے ہیں کہ *وہی* docs UI staging اور production دونوں ماحول کے ساتھ بات چیت کرے۔ |
||||
|
|
||||
|
اگر آپ `servers` کی حسب ضرورت فہرست پاس کریں اور `root_path` موجود ہو (کیونکہ آپ کا API proxy کے پیچھے ہے)، تو **FastAPI** فہرست کے شروع میں اس `root_path` کے ساتھ ایک "server" داخل کرے گا۔ |
||||
|
|
||||
|
مثال کے طور پر: |
||||
|
|
||||
|
{* ../../docs_src/behind_a_proxy/tutorial003_py310.py hl[4:7] *} |
||||
|
|
||||
|
یہ اس طرح کا OpenAPI schema بنائے گا: |
||||
|
|
||||
|
```JSON hl_lines="5-7" |
||||
|
{ |
||||
|
"openapi": "3.1.0", |
||||
|
// More stuff here |
||||
|
"servers": [ |
||||
|
{ |
||||
|
"url": "/api/v1" |
||||
|
}, |
||||
|
{ |
||||
|
"url": "https://stag.example.com", |
||||
|
"description": "Staging environment" |
||||
|
}, |
||||
|
{ |
||||
|
"url": "https://prod.example.com", |
||||
|
"description": "Production environment" |
||||
|
} |
||||
|
], |
||||
|
"paths": { |
||||
|
// More stuff here |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
غور کریں خود بخود بنایا گیا server جس کی `url` ویلیو `/api/v1` ہے، جو `root_path` سے لی گئی ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
[http://127.0.0.1:9999/api/v1/docs](http://127.0.0.1:9999/api/v1/docs) پر docs UI میں یہ اس طرح نظر آئے گا: |
||||
|
|
||||
|
<img src="/img/tutorial/behind-a-proxy/image03.png"> |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
docs UI اس server کے ساتھ بات چیت کرے گا جسے آپ منتخب کریں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
OpenAPI specification میں `servers` خاصیت اختیاری ہے۔ |
||||
|
|
||||
|
اگر آپ `servers` parameter بیان نہ کریں اور `root_path` `/` کے برابر ہو، تو بنائے گئے OpenAPI schema میں `servers` خاصیت مکمل طور پر چھوڑ دی جائے گی، جو بطور ڈیفالٹ `url` ویلیو `/` والے ایک واحد server کے برابر ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### `root_path` سے خودکار server غیر فعال کرنا { #disable-automatic-server-from-root-path } |
||||
|
|
||||
|
اگر آپ نہیں چاہتے کہ **FastAPI** `root_path` استعمال کرتے ہوئے خودکار server شامل کرے، تو آپ `root_path_in_servers=False` parameter استعمال کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/behind_a_proxy/tutorial004_py310.py hl[9] *} |
||||
|
|
||||
|
اور پھر اسے OpenAPI schema میں شامل نہیں کیا جائے گا۔ |
||||
|
|
||||
|
## Sub-application mount کرنا { #mounting-a-sub-application } |
||||
|
|
||||
|
اگر آپ کو sub-application mount کرنی ہو (جیسا کہ [Sub Applications - Mounts](sub-applications.md) میں بیان ہے) جبکہ `root_path` کے ساتھ proxy بھی استعمال ہو رہا ہو، تو آپ اسے عام طور پر کر سکتے ہیں، جیسا کہ آپ توقع کریں گے۔ |
||||
|
|
||||
|
FastAPI اندرونی طور پر `root_path` کو سمجھداری سے استعمال کرے گا، تو یہ بس کام کر جائے گا۔ |
||||
@ -0,0 +1,272 @@ |
|||||
|
# حسب ضرورت Response - HTML, Stream, File, اور دیگر { #custom-response-html-stream-file-others } |
||||
|
|
||||
|
پہلے سے طے شدہ طور پر، **FastAPI** JSON responses واپس کرے گا۔ |
||||
|
|
||||
|
آپ اسے براہ راست `Response` واپس کر کے تبدیل کر سکتے ہیں جیسا کہ [براہ راست Response واپس کریں](response-directly.md) میں بتایا گیا ہے۔ |
||||
|
|
||||
|
لیکن اگر آپ براہ راست `Response` واپس کرتے ہیں (یا کوئی بھی subclass، جیسے `JSONResponse`)، تو ڈیٹا خود بخود تبدیل نہیں ہوگا (چاہے آپ نے `response_model` کا اعلان کیا ہو)، اور دستاویزات خود بخود تیار نہیں ہوں گی (مثال کے طور پر، مخصوص "media type" شامل کرنا، HTTP header `Content-Type` میں، تیار شدہ OpenAPI کے حصے کے طور پر)۔ |
||||
|
|
||||
|
لیکن آپ وہ `Response` بھی اعلان کر سکتے ہیں جو آپ استعمال کرنا چاہتے ہیں (مثلاً کوئی بھی `Response` subclass)، *path operation decorator* میں `response_class` parameter استعمال کر کے۔ |
||||
|
|
||||
|
آپ کے *path operation function* سے واپس آنے والا مواد اس `Response` میں ڈالا جائے گا۔ |
||||
|
|
||||
|
/// note | نوٹ |
||||
|
|
||||
|
اگر آپ بغیر media type والی response class استعمال کرتے ہیں، تو FastAPI توقع کرے گا کہ آپ کے response میں کوئی مواد نہیں ہے، لہذا یہ تیار شدہ OpenAPI docs میں response format کو دستاویزی شکل نہیں دے گا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## JSON Responses { #json-responses } |
||||
|
|
||||
|
پہلے سے طے شدہ طور پر FastAPI JSON responses واپس کرتا ہے۔ |
||||
|
|
||||
|
اگر آپ [Response Model](../tutorial/response-model.md) کا اعلان کرتے ہیں تو FastAPI اسے Pydantic استعمال کر کے ڈیٹا کو JSON میں serialize کرنے کے لیے استعمال کرے گا۔ |
||||
|
|
||||
|
اگر آپ response model کا اعلان نہیں کرتے، تو FastAPI [JSON Compatible Encoder](../tutorial/encoder.md) میں بیان کردہ `jsonable_encoder` استعمال کرے گا اور اسے `JSONResponse` میں ڈالے گا۔ |
||||
|
|
||||
|
اگر آپ JSON media type (`application/json`) والی `response_class` کا اعلان کرتے ہیں، جیسا کہ `JSONResponse` کے معاملے میں ہے، تو آپ کا واپس کردہ ڈیٹا خود بخود Pydantic `response_model` کے ساتھ تبدیل (اور فلٹر) ہوگا جو آپ نے *path operation decorator* میں اعلان کیا تھا۔ لیکن ڈیٹا کو Pydantic کے ذریعے JSON bytes میں serialize نہیں کیا جائے گا، بلکہ اسے `jsonable_encoder` سے تبدیل کیا جائے گا اور پھر `JSONResponse` class کو دیا جائے گا، جو اسے Python کی معیاری JSON library استعمال کر کے bytes میں serialize کرے گی۔ |
||||
|
|
||||
|
### JSON کارکردگی { #json-performance } |
||||
|
|
||||
|
مختصراً، اگر آپ زیادہ سے زیادہ کارکردگی چاہتے ہیں تو [Response Model](../tutorial/response-model.md) استعمال کریں اور *path operation decorator* میں `response_class` کا اعلان نہ کریں۔ |
||||
|
|
||||
|
{* ../../docs_src/response_model/tutorial001_01_py310.py ln[15:17] hl[16] *} |
||||
|
|
||||
|
## HTML Response { #html-response } |
||||
|
|
||||
|
**FastAPI** سے براہ راست HTML کے ساتھ response واپس کرنے کے لیے، `HTMLResponse` استعمال کریں۔ |
||||
|
|
||||
|
* `HTMLResponse` import کریں۔ |
||||
|
* اپنے *path operation decorator* کے parameter `response_class` میں `HTMLResponse` دیں۔ |
||||
|
|
||||
|
{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *} |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
parameter `response_class` کو response کی "media type" کی تعریف کے لیے بھی استعمال کیا جائے گا۔ |
||||
|
|
||||
|
اس صورت میں، HTTP header `Content-Type` کو `text/html` پر مقرر کیا جائے گا۔ |
||||
|
|
||||
|
اور اسے OpenAPI میں اسی طرح دستاویزی شکل دی جائے گی۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### `Response` واپس کریں { #return-a-response } |
||||
|
|
||||
|
جیسا کہ [براہ راست Response واپس کریں](response-directly.md) میں بتایا گیا ہے، آپ اپنے *path operation* میں response کو براہ راست واپس کر کے بھی تبدیل کر سکتے ہیں۔ |
||||
|
|
||||
|
اوپر والی مثال، `HTMLResponse` واپس کرتے ہوئے، اس طرح دکھ سکتی ہے: |
||||
|
|
||||
|
{* ../../docs_src/custom_response/tutorial003_py310.py hl[2,7,19] *} |
||||
|
|
||||
|
/// warning | انتباہ |
||||
|
|
||||
|
آپ کے *path operation function* سے براہ راست واپس کیا گیا `Response` OpenAPI میں دستاویزی شکل نہیں دیا جائے گا (مثال کے طور پر، `Content-Type` دستاویزی نہیں ہوگا) اور خودکار انٹرایکٹو docs میں نظر نہیں آئے گا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
یقیناً، اصل `Content-Type` header، status code وغیرہ آپ کے واپس کردہ `Response` آبجیکٹ سے آئیں گے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### OpenAPI میں دستاویز بنائیں اور `Response` کو تبدیل کریں { #document-in-openapi-and-override-response } |
||||
|
|
||||
|
اگر آپ function کے اندر سے response کو تبدیل کرنا چاہتے ہیں لیکن ساتھ ہی OpenAPI میں "media type" کو دستاویزی شکل دینا چاہتے ہیں، تو آپ `response_class` parameter استعمال کر سکتے ہیں اور ساتھ ہی `Response` آبجیکٹ واپس کر سکتے ہیں۔ |
||||
|
|
||||
|
`response_class` پھر صرف OpenAPI *path operation* کی دستاویز بنانے کے لیے استعمال ہوگی، لیکن آپ کا `Response` جیسا ہے ویسا ہی استعمال ہوگا۔ |
||||
|
|
||||
|
#### براہ راست `HTMLResponse` واپس کریں { #return-an-htmlresponse-directly } |
||||
|
|
||||
|
مثال کے طور پر، یہ کچھ اس طرح ہو سکتا ہے: |
||||
|
|
||||
|
{* ../../docs_src/custom_response/tutorial004_py310.py hl[7,21,23] *} |
||||
|
|
||||
|
اس مثال میں، function `generate_html_response()` پہلے سے ہی HTML کو `str` میں واپس کرنے کی بجائے `Response` تیار اور واپس کرتا ہے۔ |
||||
|
|
||||
|
`generate_html_response()` کو کال کرنے کا نتیجہ واپس کر کے، آپ پہلے سے ہی ایک `Response` واپس کر رہے ہیں جو **FastAPI** کے پہلے سے طے شدہ رویے کو تبدیل کر دے گا۔ |
||||
|
|
||||
|
لیکن چونکہ آپ نے `HTMLResponse` کو `response_class` میں بھی دیا ہے، **FastAPI** جانے گا کہ اسے OpenAPI اور انٹرایکٹو docs میں HTML کے طور پر `text/html` کے ساتھ دستاویزی شکل کیسے دینی ہے: |
||||
|
|
||||
|
<img src="/img/tutorial/custom-response/image01.png"> |
||||
|
|
||||
|
## دستیاب responses { #available-responses } |
||||
|
|
||||
|
یہاں کچھ دستیاب responses ہیں۔ |
||||
|
|
||||
|
ذہن میں رکھیں کہ آپ `Response` استعمال کر کے کچھ بھی واپس کر سکتے ہیں، یا حتی کہ اپنی مرضی کی sub-class بنا سکتے ہیں۔ |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
آپ `from starlette.responses import HTMLResponse` بھی استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
**FastAPI** وہی `starlette.responses` فراہم کرتا ہے جو `fastapi.responses` کے طور پر، بس آپ یعنی developer کی سہولت کے لیے۔ لیکن زیادہ تر دستیاب responses براہ راست Starlette سے آتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### `Response` { #response } |
||||
|
|
||||
|
بنیادی `Response` class، باقی تمام responses اس سے وراثت میں ملتے ہیں۔ |
||||
|
|
||||
|
آپ اسے براہ راست واپس کر سکتے ہیں۔ |
||||
|
|
||||
|
یہ درج ذیل parameters قبول کرتا ہے: |
||||
|
|
||||
|
* `content` - ایک `str` یا `bytes`۔ |
||||
|
* `status_code` - ایک `int` HTTP status code۔ |
||||
|
* `headers` - strings کی ایک `dict`۔ |
||||
|
* `media_type` - media type دینے والی ایک `str`۔ مثلاً `"text/html"`۔ |
||||
|
|
||||
|
FastAPI (دراصل Starlette) خود بخود Content-Length header شامل کرے گا۔ یہ Content-Type header بھی شامل کرے گا، `media_type` کی بنیاد پر اور متنی اقسام کے لیے charset شامل کرے گا۔ |
||||
|
|
||||
|
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *} |
||||
|
|
||||
|
### `HTMLResponse` { #htmlresponse } |
||||
|
|
||||
|
کچھ متن یا bytes لیتا ہے اور HTML response واپس کرتا ہے، جیسا کہ آپ نے اوپر پڑھا۔ |
||||
|
|
||||
|
### `PlainTextResponse` { #plaintextresponse } |
||||
|
|
||||
|
کچھ متن یا bytes لیتا ہے اور سادہ متنی response واپس کرتا ہے۔ |
||||
|
|
||||
|
{* ../../docs_src/custom_response/tutorial005_py310.py hl[2,7,9] *} |
||||
|
|
||||
|
### `JSONResponse` { #jsonresponse } |
||||
|
|
||||
|
کچھ ڈیٹا لیتا ہے اور `application/json` encoded response واپس کرتا ہے۔ |
||||
|
|
||||
|
یہ **FastAPI** میں استعمال ہونے والا پہلے سے طے شدہ response ہے، جیسا کہ آپ نے اوپر پڑھا۔ |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
لیکن اگر آپ response model یا return type کا اعلان کرتے ہیں، تو اسے ڈیٹا کو JSON میں براہ راست serialize کرنے کے لیے استعمال کیا جائے گا، اور JSON کے لیے صحیح media type والا response براہ راست واپس کیا جائے گا، `JSONResponse` class استعمال کیے بغیر۔ |
||||
|
|
||||
|
یہ بہترین کارکردگی حاصل کرنے کا مثالی طریقہ ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### `RedirectResponse` { #redirectresponse } |
||||
|
|
||||
|
HTTP redirect واپس کرتا ہے۔ پہلے سے طے شدہ طور پر 307 status code (Temporary Redirect) استعمال کرتا ہے۔ |
||||
|
|
||||
|
آپ براہ راست `RedirectResponse` واپس کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/custom_response/tutorial006_py310.py hl[2,9] *} |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
یا آپ اسے `response_class` parameter میں استعمال کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/custom_response/tutorial006b_py310.py hl[2,7,9] *} |
||||
|
|
||||
|
اگر آپ ایسا کرتے ہیں، تو آپ اپنے *path operation* function سے براہ راست URL واپس کر سکتے ہیں۔ |
||||
|
|
||||
|
اس صورت میں، استعمال ہونے والا `status_code` `RedirectResponse` کا پہلے سے طے شدہ ہوگا، جو `307` ہے۔ |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
آپ `status_code` parameter کو `response_class` parameter کے ساتھ بھی استعمال کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/custom_response/tutorial006c_py310.py hl[2,7,9] *} |
||||
|
|
||||
|
### `StreamingResponse` { #streamingresponse } |
||||
|
|
||||
|
ایک async generator یا عام generator/iterator (ایک function جس میں `yield` ہو) لیتا ہے اور response body کو stream کرتا ہے۔ |
||||
|
|
||||
|
{* ../../docs_src/custom_response/tutorial007_py310.py hl[3,16] *} |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
ایک `async` task صرف اس وقت منسوخ ہو سکتا ہے جب یہ `await` پر پہنچتا ہے۔ اگر `await` نہیں ہے، تو generator (function جس میں `yield` ہو) صحیح طریقے سے منسوخ نہیں ہو سکتا اور منسوخی کی درخواست کے بعد بھی چلتا رہ سکتا ہے۔ |
||||
|
|
||||
|
چونکہ اس چھوٹی مثال کو کسی `await` statement کی ضرورت نہیں ہے، ہم `await anyio.sleep(0)` شامل کرتے ہیں تاکہ event loop کو منسوخی سنبھالنے کا موقع مل سکے۔ |
||||
|
|
||||
|
بڑے یا لامحدود streams کے ساتھ یہ اور بھی اہم ہوگا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
براہ راست `StreamingResponse` واپس کرنے کی بجائے، آپ کو شاید [Stream Data](./stream-data.md) میں دیے گئے طریقے پر عمل کرنا چاہیے، یہ بہت زیادہ آسان ہے اور پس پردہ منسوخی کو آپ کے لیے سنبھالتا ہے۔ |
||||
|
|
||||
|
اگر آپ JSON Lines stream کر رہے ہیں، تو [Stream JSON Lines](../tutorial/stream-json-lines.md) ٹیوٹوریل دیکھیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### `FileResponse` { #fileresponse } |
||||
|
|
||||
|
فائل کو غیر ہم وقتی (asynchronously) response کے طور پر stream کرتا ہے۔ |
||||
|
|
||||
|
دوسری response اقسام سے مختلف arguments لیتا ہے: |
||||
|
|
||||
|
* `path` - فائل کا path جو stream کرنی ہے۔ |
||||
|
* `headers` - شامل کرنے کے لیے کوئی بھی حسب ضرورت headers، بطور dictionary۔ |
||||
|
* `media_type` - media type دینے والی ایک string۔ اگر مقرر نہ ہو تو فائل نام یا path سے media type کا اندازہ لگایا جائے گا۔ |
||||
|
* `filename` - اگر مقرر ہو تو یہ response `Content-Disposition` میں شامل ہوگا۔ |
||||
|
|
||||
|
File responses میں مناسب `Content-Length`، `Last-Modified` اور `ETag` headers شامل ہوں گے۔ |
||||
|
|
||||
|
{* ../../docs_src/custom_response/tutorial009_py310.py hl[2,10] *} |
||||
|
|
||||
|
آپ `response_class` parameter بھی استعمال کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/custom_response/tutorial009b_py310.py hl[2,8,10] *} |
||||
|
|
||||
|
اس صورت میں، آپ اپنے *path operation* function سے براہ راست فائل کا path واپس کر سکتے ہیں۔ |
||||
|
|
||||
|
## حسب ضرورت response class { #custom-response-class } |
||||
|
|
||||
|
آپ `Response` سے وراثت میں لے کر اپنی مرضی کی response class بنا سکتے ہیں اور اسے استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
مثال کے طور پر، فرض کریں کہ آپ [`orjson`](https://github.com/ijl/orjson) کو کچھ ترتیبات کے ساتھ استعمال کرنا چاہتے ہیں۔ |
||||
|
|
||||
|
فرض کریں آپ چاہتے ہیں کہ یہ indented اور formatted JSON واپس کرے، لہذا آپ orjson آپشن `orjson.OPT_INDENT_2` استعمال کرنا چاہتے ہیں۔ |
||||
|
|
||||
|
آپ `CustomORJSONResponse` بنا سکتے ہیں۔ سب سے اہم بات یہ ہے کہ آپ کو ایک `Response.render(content)` method بنانا ہے جو مواد کو `bytes` کے طور پر واپس کرے: |
||||
|
|
||||
|
{* ../../docs_src/custom_response/tutorial009c_py310.py hl[9:14,17] *} |
||||
|
|
||||
|
اب واپس کرنے کی بجائے: |
||||
|
|
||||
|
```json |
||||
|
{"message": "Hello World"} |
||||
|
``` |
||||
|
|
||||
|
...یہ response واپس کرے گا: |
||||
|
|
||||
|
```json |
||||
|
{ |
||||
|
"message": "Hello World" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
یقیناً، آپ کو JSON فارمیٹنگ سے کہیں بہتر طریقے مل جائیں گے اس سے فائدہ اٹھانے کے لیے۔ |
||||
|
|
||||
|
### `orjson` یا Response Model { #orjson-or-response-model } |
||||
|
|
||||
|
اگر آپ کارکردگی کی تلاش میں ہیں تو شاید `orjson` response سے بہتر یہ ہے کہ آپ [Response Model](../tutorial/response-model.md) استعمال کریں۔ |
||||
|
|
||||
|
Response model کے ساتھ، FastAPI ڈیٹا کو JSON میں serialize کرنے کے لیے Pydantic استعمال کرے گا، بغیر درمیانی مراحل کے، جیسے اسے `jsonable_encoder` سے تبدیل کرنا، جو کسی بھی اور صورت میں ہوتا۔ |
||||
|
|
||||
|
اور پس پردہ، Pydantic JSON میں serialize کرنے کے لیے `orjson` جیسے ہی بنیادی Rust میکانزم استعمال کرتا ہے، لہذا response model کے ساتھ آپ کو پہلے سے ہی بہترین کارکردگی مل جائے گی۔ |
||||
|
|
||||
|
## پہلے سے طے شدہ response class { #default-response-class } |
||||
|
|
||||
|
**FastAPI** class instance یا `APIRouter` بناتے وقت آپ بتا سکتے ہیں کہ پہلے سے طے شدہ طور پر کون سی response class استعمال ہو۔ |
||||
|
|
||||
|
اسے بیان کرنے والا parameter `default_response_class` ہے۔ |
||||
|
|
||||
|
نیچے دی گئی مثال میں، **FastAPI** تمام *path operations* میں JSON کی بجائے پہلے سے طے شدہ طور پر `HTMLResponse` استعمال کرے گا۔ |
||||
|
|
||||
|
{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *} |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
آپ پہلے کی طرح *path operations* میں `response_class` کو تبدیل کر سکتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## اضافی دستاویزات { #additional-documentation } |
||||
|
|
||||
|
آپ OpenAPI میں media type اور بہت سی دوسری تفصیلات کا بھی `responses` استعمال کر کے اعلان کر سکتے ہیں: [OpenAPI میں اضافی Responses](additional-responses.md)۔ |
||||
@ -0,0 +1,95 @@ |
|||||
|
# Dataclasses کا استعمال { #using-dataclasses } |
||||
|
|
||||
|
FastAPI **Pydantic** کے اوپر بنایا گیا ہے، اور میں آپ کو دکھاتا رہا ہوں کہ requests اور responses بیان کرنے کے لیے Pydantic models کیسے استعمال کریں۔ |
||||
|
|
||||
|
لیکن FastAPI [`dataclasses`](https://docs.python.org/3/library/dataclasses.html) استعمال کرنے کی بھی اسی طرح سپورٹ کرتا ہے: |
||||
|
|
||||
|
{* ../../docs_src/dataclasses_/tutorial001_py310.py hl[1,6:11,18:19] *} |
||||
|
|
||||
|
یہ **Pydantic** کی بدولت اب بھی سپورٹ ہے، کیونکہ اس میں [`dataclasses` کی اندرونی سپورٹ](https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel) موجود ہے۔ |
||||
|
|
||||
|
تو، اوپر والے کوڈ میں بھی جو واضح طور پر Pydantic استعمال نہیں کرتا، FastAPI ان معیاری dataclasses کو Pydantic کے اپنے مخصوص dataclasses میں تبدیل کرنے کے لیے Pydantic استعمال کر رہا ہے۔ |
||||
|
|
||||
|
اور یقیناً، یہ وہی سب سپورٹ کرتا ہے: |
||||
|
|
||||
|
* ڈیٹا validation |
||||
|
* ڈیٹا serialization |
||||
|
* ڈیٹا دستاویزات، وغیرہ۔ |
||||
|
|
||||
|
یہ Pydantic models کی طرح ہی کام کرتا ہے۔ اور یہ دراصل اندرونی طور پر اسی طرح حاصل کیا جاتا ہے، Pydantic استعمال کرتے ہوئے۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
یاد رکھیں کہ dataclasses وہ سب کچھ نہیں کر سکتیں جو Pydantic models کر سکتے ہیں۔ |
||||
|
|
||||
|
تو، آپ کو پھر بھی Pydantic models استعمال کرنے کی ضرورت پڑ سکتی ہے۔ |
||||
|
|
||||
|
لیکن اگر آپ کے پاس بہت سی dataclasses پڑی ہیں تو FastAPI استعمال کر کے web API بنانے کے لیے انہیں استعمال کرنا ایک اچھی تدبیر ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## `response_model` میں Dataclasses { #dataclasses-in-response-model } |
||||
|
|
||||
|
آپ `response_model` parameter میں بھی `dataclasses` استعمال کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/dataclasses_/tutorial002_py310.py hl[1,6:12,18] *} |
||||
|
|
||||
|
dataclass خود بخود Pydantic dataclass میں تبدیل ہو جائے گی۔ |
||||
|
|
||||
|
اس طرح، اس کا schema API docs user interface میں نظر آئے گا: |
||||
|
|
||||
|
<img src="/img/tutorial/dataclasses/image01.png"> |
||||
|
|
||||
|
## نیسٹڈ ڈیٹا ڈھانچوں میں Dataclasses { #dataclasses-in-nested-data-structures } |
||||
|
|
||||
|
آپ `dataclasses` کو دوسری type annotations کے ساتھ ملا کر نیسٹڈ ڈیٹا ڈھانچے بنا سکتے ہیں۔ |
||||
|
|
||||
|
بعض صورتوں میں، آپ کو پھر بھی Pydantic کے ورژن کی `dataclasses` استعمال کرنی ہو سکتی ہیں۔ مثال کے طور پر، اگر خود بخود بنائی گئی API دستاویزات میں غلطیاں ہوں۔ |
||||
|
|
||||
|
اس صورت میں، آپ معیاری `dataclasses` کو `pydantic.dataclasses` سے بدل سکتے ہیں، جو ایک متبادل ہے: |
||||
|
|
||||
|
{* ../../docs_src/dataclasses_/tutorial003_py310.py hl[1,4,7:10,13:16,22:24,27] *} |
||||
|
|
||||
|
1. ہم پھر بھی معیاری `dataclasses` سے `field` import کرتے ہیں۔ |
||||
|
|
||||
|
2. `pydantic.dataclasses` `dataclasses` کا متبادل ہے۔ |
||||
|
|
||||
|
3. `Author` dataclass میں `Item` dataclasses کی فہرست شامل ہے۔ |
||||
|
|
||||
|
4. `Author` dataclass `response_model` parameter کے طور پر استعمال ہوتی ہے۔ |
||||
|
|
||||
|
5. آپ dataclasses کے ساتھ دیگر معیاری type annotations کو request body کے طور پر استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
اس صورت میں، یہ `Item` dataclasses کی فہرست ہے۔ |
||||
|
|
||||
|
6. یہاں ہم dictionary واپس کر رہے ہیں جس میں `items` ہے جو dataclasses کی فہرست ہے۔ |
||||
|
|
||||
|
FastAPI پھر بھی ڈیٹا کو JSON میں <dfn title="ڈیٹا کو ایسی شکل میں تبدیل کرنا جو منتقل کی جا سکے">serialize</dfn> کرنے کے قابل ہے۔ |
||||
|
|
||||
|
7. یہاں `response_model` `Author` dataclasses کی فہرست کی type annotation استعمال کر رہا ہے۔ |
||||
|
|
||||
|
دوبارہ، آپ `dataclasses` کو معیاری type annotations کے ساتھ ملا سکتے ہیں۔ |
||||
|
|
||||
|
8. غور کریں کہ یہ *path operation function* `async def` کی بجائے عام `def` استعمال کرتا ہے۔ |
||||
|
|
||||
|
ہمیشہ کی طرح، FastAPI میں آپ `def` اور `async def` کو ضرورت کے مطابق ملا سکتے ہیں۔ |
||||
|
|
||||
|
اگر آپ کو یاد دہانی چاہیے کہ کب کون سا استعمال کریں، تو [`async` اور `await`](../async.md#in-a-hurry) کی دستاویزات میں _"جلدی میں ہیں؟"_ سیکشن دیکھیں۔ |
||||
|
|
||||
|
9. یہ *path operation function* dataclasses واپس نہیں کر رہا (حالانکہ کر سکتا ہے)، بلکہ اندرونی ڈیٹا کے ساتھ dictionaries کی فہرست واپس کر رہا ہے۔ |
||||
|
|
||||
|
FastAPI `response_model` parameter (جس میں dataclasses شامل ہیں) استعمال کرکے response تبدیل کرے گا۔ |
||||
|
|
||||
|
آپ `dataclasses` کو دیگر type annotations کے ساتھ بہت سے مختلف مجموعوں میں ملا کر پیچیدہ ڈیٹا ڈھانچے بنا سکتے ہیں۔ |
||||
|
|
||||
|
مزید مخصوص تفصیلات دیکھنے کے لیے اوپر کوڈ میں موجود annotation مشورے دیکھیں۔ |
||||
|
|
||||
|
## مزید جانیں { #learn-more } |
||||
|
|
||||
|
آپ `dataclasses` کو دیگر Pydantic models کے ساتھ بھی ملا سکتے ہیں، ان سے inherit کر سکتے ہیں، انہیں اپنے models میں شامل کر سکتے ہیں، وغیرہ۔ |
||||
|
|
||||
|
مزید جاننے کے لیے، [dataclasses کے بارے میں Pydantic دستاویزات](https://docs.pydantic.dev/latest/concepts/dataclasses/) دیکھیں۔ |
||||
|
|
||||
|
## ورژن { #version } |
||||
|
|
||||
|
یہ FastAPI ورژن `0.67.0` سے دستیاب ہے۔ |
||||
@ -0,0 +1,165 @@ |
|||||
|
# Lifespan Events { #lifespan-events } |
||||
|
|
||||
|
آپ ایسی منطق (کوڈ) بیان کر سکتے ہیں جو ایپلیکیشن **شروع ہونے** سے پہلے عمل میں آئے۔ اس کا مطلب ہے کہ یہ کوڈ ایپلیکیشن کے **requests وصول کرنا شروع** کرنے سے **پہلے**، **ایک بار** عمل میں آئے گا۔ |
||||
|
|
||||
|
اسی طرح، آپ ایسی منطق (کوڈ) بیان کر سکتے ہیں جو ایپلیکیشن کے **بند ہونے** کے وقت عمل میں آئے۔ اس صورت میں، یہ کوڈ ممکنہ طور پر **بہت سی requests** ہینڈل کرنے کے **بعد**، **ایک بار** عمل میں آئے گا۔ |
||||
|
|
||||
|
چونکہ یہ کوڈ ایپلیکیشن کے requests لینا **شروع** کرنے سے پہلے عمل میں آتا ہے، اور requests ہینڈل کرنا **ختم** کرنے کے فوراً بعد، یہ پوری ایپلیکیشن کی **lifespan** کا احاطہ کرتا ہے (لفظ "lifespan" ایک لمحے میں اہم ہوگا)۔ |
||||
|
|
||||
|
یہ ایسے **وسائل** سیٹ اپ کرنے کے لیے بہت مفید ہو سکتا ہے جو آپ کو پوری ایپ میں استعمال کرنے ہیں، اور جو requests کے درمیان **مشترک** ہیں، اور/یا جنہیں آپ کو بعد میں **صاف** کرنا ہے۔ مثال کے طور پر، database connection pool، یا مشترکہ machine learning model لوڈ کرنا۔ |
||||
|
|
||||
|
## استعمال کی صورت { #use-case } |
||||
|
|
||||
|
آئیے ایک مثال **استعمال کی صورت** سے شروع کریں اور پھر دیکھیں کہ اسے کیسے حل کیا جائے۔ |
||||
|
|
||||
|
فرض کریں کہ آپ کے پاس کچھ **machine learning models** ہیں جو آپ requests ہینڈل کرنے کے لیے استعمال کرنا چاہتے ہیں۔ |
||||
|
|
||||
|
وہی models requests کے درمیان مشترک ہیں، تو یہ ہر request کے لیے ایک model نہیں، یا ہر صارف کے لیے ایک یا اس جیسی کوئی بات نہیں۔ |
||||
|
|
||||
|
فرض کریں کہ model لوڈ کرنے میں **کافی وقت** لگ سکتا ہے، کیونکہ اسے **ڈسک سے بہت سا ڈیٹا** پڑھنا ہوتا ہے۔ تو آپ ہر request پر یہ نہیں کرنا چاہتے۔ |
||||
|
|
||||
|
آپ اسے module/فائل کی اعلیٰ سطح پر لوڈ کر سکتے ہیں، لیکن اس کا مطلب یہ بھی ہوگا کہ اگر آپ صرف ایک سادہ خودکار ٹیسٹ چلا رہے ہیں تو بھی یہ **model لوڈ** کرے گا، پھر وہ ٹیسٹ **سست** ہوگا کیونکہ اسے کوڈ کا آزاد حصہ چلانے سے پہلے model لوڈ ہونے کا انتظار کرنا ہوگا۔ |
||||
|
|
||||
|
یہی ہم حل کریں گے، requests ہینڈل ہونے سے پہلے model لوڈ کریں، لیکن صرف ایپلیکیشن کے requests وصول کرنا شروع کرنے سے ٹھیک پہلے، نہ کہ جب کوڈ لوڈ ہو رہا ہو۔ |
||||
|
|
||||
|
## Lifespan { #lifespan } |
||||
|
|
||||
|
آپ `FastAPI` ایپ کے `lifespan` parameter اور ایک "context manager" استعمال کرکے یہ *startup* اور *shutdown* منطق بیان کر سکتے ہیں (میں آپ کو ایک لمحے میں بتاؤں گا کہ یہ کیا ہے)۔ |
||||
|
|
||||
|
آئیے ایک مثال سے شروع کریں اور پھر تفصیل سے دیکھیں۔ |
||||
|
|
||||
|
ہم `yield` کے ساتھ ایک async function `lifespan()` اس طرح بناتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/events/tutorial003_py310.py hl[16,19] *} |
||||
|
|
||||
|
یہاں ہم model لوڈ کرنے کے مہنگے *startup* عمل کی نقل کر رہے ہیں (جعلی) model function کو `yield` سے پہلے machine learning models کی dictionary میں رکھ کر۔ یہ کوڈ ایپلیکیشن کے **requests لینا شروع** کرنے سے **پہلے**، *startup* کے دوران عمل میں آئے گا۔ |
||||
|
|
||||
|
اور پھر، `yield` کے فوراً بعد، ہم model کو unload کرتے ہیں۔ یہ کوڈ ایپلیکیشن کے **requests ہینڈل کرنا ختم** کرنے کے **بعد**، *shutdown* سے ٹھیک پہلے عمل میں آئے گا۔ یہ مثال کے طور پر، memory یا GPU جیسے وسائل آزاد کر سکتا ہے۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
`shutdown` تب ہوگا جب آپ ایپلیکیشن **بند** کر رہے ہوں۔ |
||||
|
|
||||
|
شاید آپ کو نیا ورژن شروع کرنا ہو، یا آپ بس اسے چلاتے چلاتے تھک گئے ہوں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### Lifespan function { #lifespan-function } |
||||
|
|
||||
|
سب سے پہلے غور کریں کہ ہم `yield` کے ساتھ ایک async function بیان کر رہے ہیں۔ یہ `yield` والی Dependencies سے بہت ملتا جلتا ہے۔ |
||||
|
|
||||
|
{* ../../docs_src/events/tutorial003_py310.py hl[14:19] *} |
||||
|
|
||||
|
function کا پہلا حصہ، `yield` سے پہلے، ایپلیکیشن شروع ہونے سے **پہلے** عمل میں آئے گا۔ |
||||
|
|
||||
|
اور `yield` کے بعد والا حصہ ایپلیکیشن ختم ہونے کے **بعد** عمل میں آئے گا۔ |
||||
|
|
||||
|
### Async Context Manager { #async-context-manager } |
||||
|
|
||||
|
اگر آپ دیکھیں، تو function کو `@asynccontextmanager` سے decorate کیا گیا ہے۔ |
||||
|
|
||||
|
یہ function کو "**async context manager**" نامی چیز میں تبدیل کرتا ہے۔ |
||||
|
|
||||
|
{* ../../docs_src/events/tutorial003_py310.py hl[1,13] *} |
||||
|
|
||||
|
Python میں **context manager** وہ چیز ہے جسے آپ `with` statement میں استعمال کر سکتے ہیں، مثال کے طور پر، `open()` context manager کے طور پر استعمال ہو سکتا ہے: |
||||
|
|
||||
|
```Python |
||||
|
with open("file.txt") as file: |
||||
|
file.read() |
||||
|
``` |
||||
|
|
||||
|
Python کے حالیہ ورژنز میں، ایک **async context manager** بھی ہے۔ آپ اسے `async with` کے ساتھ استعمال کریں گے: |
||||
|
|
||||
|
```Python |
||||
|
async with lifespan(app): |
||||
|
await do_stuff() |
||||
|
``` |
||||
|
|
||||
|
جب آپ اوپر کی طرح context manager یا async context manager بناتے ہیں، تو یہ `with` بلاک میں داخل ہونے سے پہلے `yield` سے پہلے والا کوڈ عمل میں لائے گا، اور `with` بلاک سے باہر نکلنے کے بعد `yield` کے بعد والا کوڈ عمل میں لائے گا۔ |
||||
|
|
||||
|
ہماری اوپر والی کوڈ مثال میں، ہم اسے براہ راست استعمال نہیں کرتے، بلکہ FastAPI کو استعمال کرنے کے لیے پاس کرتے ہیں۔ |
||||
|
|
||||
|
`FastAPI` ایپ کا `lifespan` parameter ایک **async context manager** لیتا ہے، تو ہم اپنا نیا `lifespan` async context manager اسے پاس کر سکتے ہیں۔ |
||||
|
|
||||
|
{* ../../docs_src/events/tutorial003_py310.py hl[22] *} |
||||
|
|
||||
|
## متبادل Events (deprecated) { #alternative-events-deprecated } |
||||
|
|
||||
|
/// warning | انتباہ |
||||
|
|
||||
|
*startup* اور *shutdown* کو ہینڈل کرنے کا تجویز کردہ طریقہ اوپر بیان کردہ `FastAPI` ایپ کا `lifespan` parameter استعمال کرنا ہے۔ اگر آپ `lifespan` parameter فراہم کریں تو `startup` اور `shutdown` event handlers مزید نہیں بلائے جائیں گے۔ یہ یا تو سب `lifespan` ہے یا سب events، دونوں نہیں۔ |
||||
|
|
||||
|
آپ شاید اس حصے کو چھوڑ سکتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
*startup* اور *shutdown* کے دوران عمل میں آنے والی منطق بیان کرنے کا ایک متبادل طریقہ ہے۔ |
||||
|
|
||||
|
آپ ایسے event handler functions بیان کر سکتے ہیں جو ایپلیکیشن شروع ہونے سے پہلے، یا بند ہوتے وقت عمل میں آنے چاہییں۔ |
||||
|
|
||||
|
یہ functions `async def` یا عام `def` کے ساتھ بیان کیے جا سکتے ہیں۔ |
||||
|
|
||||
|
### `startup` event { #startup-event } |
||||
|
|
||||
|
ایسا function شامل کرنے کے لیے جو ایپلیکیشن شروع ہونے سے پہلے چلے، اسے `"startup"` event کے ساتھ بیان کریں: |
||||
|
|
||||
|
{* ../../docs_src/events/tutorial001_py310.py hl[8] *} |
||||
|
|
||||
|
اس صورت میں، `startup` event handler function آئٹمز کے "database" (صرف ایک `dict`) کو کچھ اقدار سے شروع کرے گا۔ |
||||
|
|
||||
|
آپ ایک سے زیادہ event handler functions شامل کر سکتے ہیں۔ |
||||
|
|
||||
|
اور آپ کی ایپلیکیشن تب تک requests وصول کرنا شروع نہیں کرے گی جب تک تمام `startup` event handlers مکمل نہیں ہو جاتے۔ |
||||
|
|
||||
|
### `shutdown` event { #shutdown-event } |
||||
|
|
||||
|
ایسا function شامل کرنے کے لیے جو ایپلیکیشن بند ہوتے وقت چلے، اسے `"shutdown"` event کے ساتھ بیان کریں: |
||||
|
|
||||
|
{* ../../docs_src/events/tutorial002_py310.py hl[6] *} |
||||
|
|
||||
|
یہاں، `shutdown` event handler function `log.txt` فائل میں ایک ٹیکسٹ لائن `"Application shutdown"` لکھے گا۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
`open()` function میں، `mode="a"` کا مطلب "append" ہے، تو لائن فائل میں پہلے سے موجود مواد کو مٹائے بغیر آخر میں شامل ہوگی۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
غور کریں کہ اس صورت میں ہم معیاری Python `open()` function استعمال کر رہے ہیں جو فائل کے ساتھ بات چیت کرتا ہے۔ |
||||
|
|
||||
|
تو، اس میں I/O (input/output) شامل ہے، جس کے لیے ڈسک پر لکھے جانے کا "انتظار" کرنا ہوتا ہے۔ |
||||
|
|
||||
|
لیکن `open()` `async` اور `await` استعمال نہیں کرتا۔ |
||||
|
|
||||
|
تو، ہم event handler function کو `async def` کی بجائے معیاری `def` کے ساتھ بیان کرتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### `startup` اور `shutdown` ایک ساتھ { #startup-and-shutdown-together } |
||||
|
|
||||
|
بہت زیادہ امکان ہے کہ آپ کی *startup* اور *shutdown* منطق آپس میں جڑی ہوئی ہے، آپ شاید کچھ شروع کرنا اور پھر ختم کرنا چاہیں، کوئی وسیلہ حاصل کرنا اور پھر آزاد کرنا چاہیں وغیرہ۔ |
||||
|
|
||||
|
یہ الگ functions میں کرنا جو منطق یا متغیرات شیئر نہیں کرتے، زیادہ مشکل ہے کیونکہ آپ کو اقدار global variables یا اسی طرح کی تدبیروں میں محفوظ کرنی ہوں گی۔ |
||||
|
|
||||
|
اسی لیے، اب تجویز یہ ہے کہ اوپر بیان کردہ `lifespan` استعمال کریں۔ |
||||
|
|
||||
|
## تکنیکی تفصیلات { #technical-details } |
||||
|
|
||||
|
متجسس لوگوں کے لیے صرف ایک تکنیکی تفصیل۔ |
||||
|
|
||||
|
اندرونی طور پر، ASGI تکنیکی specification میں، یہ [Lifespan Protocol](https://asgi.readthedocs.io/en/latest/specs/lifespan.html) کا حصہ ہے، اور یہ `startup` اور `shutdown` نامی events بیان کرتا ہے۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
آپ Starlette کے `lifespan` handlers کے بارے میں مزید [Starlette کی Lifespan دستاویزات](https://www.starlette.dev/lifespan/) میں پڑھ سکتے ہیں۔ |
||||
|
|
||||
|
بشمول یہ کہ lifespan state کو کیسے ہینڈل کریں جو آپ کے کوڈ کے دوسرے حصوں میں استعمال ہو سکتا ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Sub Applications { #sub-applications } |
||||
|
|
||||
|
یاد رکھیں کہ یہ lifespan events (startup اور shutdown) صرف مرکزی ایپلیکیشن کے لیے عمل میں آئیں گے، [Sub Applications - Mounts](sub-applications.md) کے لیے نہیں۔ |
||||
@ -0,0 +1,208 @@ |
|||||
|
# SDKs بنانا { #generating-sdks } |
||||
|
|
||||
|
چونکہ **FastAPI** **OpenAPI** specification پر مبنی ہے، اس کے APIs کو ایک معیاری فارمیٹ میں بیان کیا جا سکتا ہے جسے بہت سے ٹولز سمجھتے ہیں۔ |
||||
|
|
||||
|
اس سے تازہ ترین **دستاویزات**، متعدد زبانوں میں client لائبریریاں (<abbr title="Software Development Kits">**SDKs**</abbr>)، اور **testing** یا **automation workflows** بنانا آسان ہو جاتا ہے جو آپ کے کوڈ کے ساتھ ہم آہنگ رہتے ہیں۔ |
||||
|
|
||||
|
اس گائیڈ میں، آپ سیکھیں گے کہ اپنے FastAPI backend کے لیے **TypeScript SDK** کیسے بنائیں۔ |
||||
|
|
||||
|
## اوپن سورس SDK Generators { #open-source-sdk-generators } |
||||
|
|
||||
|
ایک ورسٹائل آپشن [OpenAPI Generator](https://openapi-generator.tech/) ہے، جو **بہت سی پروگرامنگ زبانوں** کو سپورٹ کرتا ہے اور آپ کی OpenAPI specification سے SDKs بنا سکتا ہے۔ |
||||
|
|
||||
|
**TypeScript clients** کے لیے، [Hey API](https://heyapi.dev/) ایک مقصد کے لیے بنایا گیا حل ہے، جو TypeScript ایکو سسٹم کے لیے بہترین تجربہ فراہم کرتا ہے۔ |
||||
|
|
||||
|
آپ [OpenAPI.Tools](https://openapi.tools/#sdk) پر مزید SDK generators دریافت کر سکتے ہیں۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
FastAPI خود بخود **OpenAPI 3.1** specifications بناتا ہے، لہذا آپ جو بھی ٹول استعمال کریں اسے اس ورژن کو سپورٹ کرنا ضروری ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## FastAPI کے اسپانسرز سے SDK Generators { #sdk-generators-from-fastapi-sponsors } |
||||
|
|
||||
|
یہ سیکشن FastAPI کے اسپانسر کمپنیوں کے **وینچر بیکڈ** اور **کمپنی سپورٹ یافتہ** حل نمایاں کرتا ہے۔ یہ پروڈکٹس اعلیٰ معیار کی بنائی گئی SDKs کے ساتھ **اضافی خصوصیات** اور **integrations** فراہم کرتے ہیں۔ |
||||
|
|
||||
|
**FastAPI** کو ✨ [**اسپانسر**](../help-fastapi.md#sponsor-the-author) ✨ کرکے، یہ کمپنیاں framework اور اس کے **ایکو سسٹم** کو صحت مند اور **پائیدار** رکھنے میں مدد کرتی ہیں۔ |
||||
|
|
||||
|
ان کی اسپانسرشپ FastAPI **کمیونٹی** (آپ) کے ساتھ مضبوط وابستگی بھی ظاہر کرتی ہے، یہ دکھاتے ہوئے کہ وہ نہ صرف **بہترین سروس** فراہم کرنے بلکہ ایک **مضبوط اور ترقی پذیر framework**، FastAPI، کو سپورٹ کرنے میں بھی دلچسپی رکھتے ہیں۔ |
||||
|
|
||||
|
مثال کے طور پر، آپ آزما سکتے ہیں: |
||||
|
|
||||
|
* [Speakeasy](https://speakeasy.com/editor?utm_source=fastapi+repo&utm_medium=github+sponsorship) |
||||
|
* [Stainless](https://www.stainless.com/?utm_source=fastapi&utm_medium=referral) |
||||
|
* [liblab](https://developers.liblab.com/tutorials/sdk-for-fastapi?utm_source=fastapi) |
||||
|
|
||||
|
ان میں سے کچھ حل اوپن سورس بھی ہو سکتے ہیں یا مفت درجے پیش کر سکتے ہیں، تو آپ انہیں بغیر مالی وابستگی کے آزما سکتے ہیں۔ دیگر تجارتی SDK generators بھی دستیاب ہیں اور آن لائن مل سکتے ہیں۔ |
||||
|
|
||||
|
## TypeScript SDK بنائیں { #create-a-typescript-sdk } |
||||
|
|
||||
|
آئیے ایک سادہ FastAPI ایپلیکیشن سے شروع کریں: |
||||
|
|
||||
|
{* ../../docs_src/generate_clients/tutorial001_py310.py hl[7:9,12:13,16:17,21] *} |
||||
|
|
||||
|
غور کریں کہ *path operations* اپنے استعمال شدہ models کو request payload اور response payload کے لیے بیان کرتے ہیں، `Item` اور `ResponseMessage` models استعمال کرتے ہوئے۔ |
||||
|
|
||||
|
### API Docs { #api-docs } |
||||
|
|
||||
|
اگر آپ `/docs` پر جائیں تو آپ دیکھیں گے کہ اس میں requests میں بھیجے جانے والے اور responses میں وصول ہونے والے ڈیٹا کے **schemas** موجود ہیں: |
||||
|
|
||||
|
<img src="/img/tutorial/generate-clients/image01.png"> |
||||
|
|
||||
|
آپ وہ schemas اس لیے دیکھ سکتے ہیں کیونکہ وہ ایپ میں models کے ساتھ بیان کیے گئے تھے۔ |
||||
|
|
||||
|
وہ معلومات ایپ کے **OpenAPI schema** میں دستیاب ہیں، اور پھر API docs میں دکھائی جاتی ہیں۔ |
||||
|
|
||||
|
OpenAPI میں شامل models کی وہی معلومات **client کوڈ بنانے** کے لیے استعمال ہو سکتی ہیں۔ |
||||
|
|
||||
|
### Hey API { #hey-api } |
||||
|
|
||||
|
جب ہمارے پاس models والی FastAPI ایپ ہو تو ہم TypeScript client بنانے کے لیے Hey API استعمال کر سکتے ہیں۔ اس کا سب سے تیز طریقہ npx کے ذریعے ہے۔ |
||||
|
|
||||
|
```sh |
||||
|
npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client |
||||
|
``` |
||||
|
|
||||
|
یہ `./src/client` میں TypeScript SDK بنائے گا۔ |
||||
|
|
||||
|
آپ [`@hey-api/openapi-ts` انسٹال کرنے](https://heyapi.dev/openapi-ts/get-started) اور [بنائے گئے output](https://heyapi.dev/openapi-ts/output) کے بارے میں ان کی ویب سائٹ پر پڑھ سکتے ہیں۔ |
||||
|
|
||||
|
### SDK استعمال کرنا { #using-the-sdk } |
||||
|
|
||||
|
اب آپ client کوڈ import اور استعمال کر سکتے ہیں۔ یہ کچھ اس طرح نظر آ سکتا ہے، غور کریں کہ آپ کو methods کے لیے autocompletion ملتا ہے: |
||||
|
|
||||
|
<img src="/img/tutorial/generate-clients/image02.png"> |
||||
|
|
||||
|
آپ کو بھیجے جانے والے payload کے لیے بھی autocompletion ملے گا: |
||||
|
|
||||
|
<img src="/img/tutorial/generate-clients/image03.png"> |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
`name` اور `price` کے لیے autocompletion غور کریں، جو FastAPI ایپلیکیشن میں `Item` model میں بیان کیے گئے تھے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
آپ کو بھیجے جانے والے ڈیٹا کے لیے inline errors بھی ملیں گے: |
||||
|
|
||||
|
<img src="/img/tutorial/generate-clients/image04.png"> |
||||
|
|
||||
|
response آبجیکٹ میں بھی autocompletion ہوگا: |
||||
|
|
||||
|
<img src="/img/tutorial/generate-clients/image05.png"> |
||||
|
|
||||
|
## Tags کے ساتھ FastAPI ایپ { #fastapi-app-with-tags } |
||||
|
|
||||
|
بہت سے معاملات میں، آپ کی FastAPI ایپ بڑی ہوگی، اور آپ شاید *path operations* کے مختلف گروپس الگ کرنے کے لیے tags استعمال کریں گے۔ |
||||
|
|
||||
|
مثال کے طور پر، آپ کے پاس **items** کا سیکشن اور **users** کا الگ سیکشن ہو سکتا ہے، اور وہ tags سے الگ ہو سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/generate_clients/tutorial002_py310.py hl[21,26,34] *} |
||||
|
|
||||
|
### Tags کے ساتھ TypeScript Client بنائیں { #generate-a-typescript-client-with-tags } |
||||
|
|
||||
|
اگر آپ tags استعمال کرنے والی FastAPI ایپ کے لیے client بنائیں، تو یہ عام طور پر tags کی بنیاد پر client کوڈ کو الگ بھی کرے گا۔ |
||||
|
|
||||
|
اس طریقے سے، آپ کو client کوڈ میں چیزیں درست ترتیب اور گروپنگ میں ملیں گی: |
||||
|
|
||||
|
<img src="/img/tutorial/generate-clients/image06.png"> |
||||
|
|
||||
|
اس صورت میں، آپ کے پاس ہیں: |
||||
|
|
||||
|
* `ItemsService` |
||||
|
* `UsersService` |
||||
|
|
||||
|
### Client Method کے نام { #client-method-names } |
||||
|
|
||||
|
اس وقت، بنائے گئے method کے نام جیسے `createItemItemsPost` بہت صاف نہیں لگتے: |
||||
|
|
||||
|
```TypeScript |
||||
|
ItemsService.createItemItemsPost({name: "Plumbus", price: 5}) |
||||
|
``` |
||||
|
|
||||
|
...اس کی وجہ یہ ہے کہ client generator ہر *path operation* کے لیے OpenAPI کا اندرونی **operation ID** استعمال کرتا ہے۔ |
||||
|
|
||||
|
OpenAPI تقاضا کرتا ہے کہ ہر operation ID تمام *path operations* میں منفرد ہو، اس لیے FastAPI اس operation ID کو بنانے کے لیے **function کا نام**، **path**، اور **HTTP method/operation** استعمال کرتا ہے، کیونکہ اس طرح یہ یقینی بنا سکتا ہے کہ operation IDs منفرد ہیں۔ |
||||
|
|
||||
|
لیکن میں آپ کو اگلے حصے میں دکھاؤں گا کہ اسے کیسے بہتر بنائیں۔ |
||||
|
|
||||
|
## حسب ضرورت Operation IDs اور بہتر Method نام { #custom-operation-ids-and-better-method-names } |
||||
|
|
||||
|
آپ ان operation IDs کی **بنانے کے طریقے کو تبدیل** کر سکتے ہیں تاکہ وہ آسان ہوں اور clients میں **آسان method نام** ہوں۔ |
||||
|
|
||||
|
اس صورت میں، آپ کو یقینی بنانا ہوگا کہ ہر operation ID کسی اور طریقے سے **منفرد** ہو۔ |
||||
|
|
||||
|
مثال کے طور پر، آپ یقینی بنا سکتے ہیں کہ ہر *path operation* میں ایک tag ہو، اور پھر **tag** اور *path operation* کے **نام** (function نام) کی بنیاد پر operation ID بنائیں۔ |
||||
|
|
||||
|
### حسب ضرورت Unique ID Function بنائیں { #custom-generate-unique-id-function } |
||||
|
|
||||
|
FastAPI ہر *path operation* کے لیے ایک **unique ID** استعمال کرتا ہے، جو **operation ID** کے لیے اور requests یا responses کے لیے کسی ضروری حسب ضرورت models کے ناموں کے لیے بھی استعمال ہوتا ہے۔ |
||||
|
|
||||
|
آپ اس function کو حسب ضرورت بنا سکتے ہیں۔ یہ ایک `APIRoute` لیتا ہے اور string واپس کرتا ہے۔ |
||||
|
|
||||
|
مثال کے طور پر، یہاں یہ پہلا tag (آپ کے پاس شاید صرف ایک tag ہوگا) اور *path operation* کا نام (function نام) استعمال کر رہا ہے۔ |
||||
|
|
||||
|
پھر آپ اس حسب ضرورت function کو **FastAPI** کو `generate_unique_id_function` parameter کے طور پر پاس کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/generate_clients/tutorial003_py310.py hl[6:7,10] *} |
||||
|
|
||||
|
### حسب ضرورت Operation IDs کے ساتھ TypeScript Client بنائیں { #generate-a-typescript-client-with-custom-operation-ids } |
||||
|
|
||||
|
اب، اگر آپ دوبارہ client بنائیں تو آپ دیکھیں گے کہ اس میں بہتر method نام ہیں: |
||||
|
|
||||
|
<img src="/img/tutorial/generate-clients/image07.png"> |
||||
|
|
||||
|
جیسا کہ آپ دیکھ سکتے ہیں، method ناموں میں اب tag اور پھر function نام ہے، اب ان میں URL path اور HTTP operation کی معلومات شامل نہیں ہیں۔ |
||||
|
|
||||
|
### Client Generator کے لیے OpenAPI Specification پری پروسیس کریں { #preprocess-the-openapi-specification-for-the-client-generator } |
||||
|
|
||||
|
بنائے گئے کوڈ میں ابھی بھی کچھ **دہرائی ہوئی معلومات** ہیں۔ |
||||
|
|
||||
|
ہم پہلے ہی جانتے ہیں کہ یہ method **items** سے متعلق ہے کیونکہ وہ لفظ `ItemsService` (tag سے لیا گیا) میں ہے، لیکن method نام میں بھی tag نام prefix ہے۔ |
||||
|
|
||||
|
ہم شاید اسے عام طور پر OpenAPI کے لیے رکھنا چاہیں گے، کیونکہ یہ یقینی بنائے گا کہ operation IDs **منفرد** ہیں۔ |
||||
|
|
||||
|
لیکن بنائے گئے client کے لیے، ہم clients بنانے سے بالکل پہلے OpenAPI operation IDs **تبدیل** کر سکتے ہیں، تاکہ وہ method نام بہتر اور **صاف** ہوں۔ |
||||
|
|
||||
|
ہم OpenAPI JSON کو `openapi.json` فائل میں ڈاؤن لوڈ کر سکتے ہیں اور پھر اس script سے **وہ prefix tag ہٹا** سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/generate_clients/tutorial004_py310.py *} |
||||
|
|
||||
|
//// tab | Node.js |
||||
|
|
||||
|
```Javascript |
||||
|
{!> ../../docs_src/generate_clients/tutorial004.js!} |
||||
|
``` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
اس سے، operation IDs `items-get_items` جیسی چیزوں سے صرف `get_items` میں تبدیل ہو جائیں گے، اس طریقے سے client generator آسان method نام بنا سکتا ہے۔ |
||||
|
|
||||
|
### پری پروسیس شدہ OpenAPI کے ساتھ TypeScript Client بنائیں { #generate-a-typescript-client-with-the-preprocessed-openapi } |
||||
|
|
||||
|
چونکہ آخری نتیجہ اب `openapi.json` فائل میں ہے، آپ کو اپنی input location اپ ڈیٹ کرنی ہوگی: |
||||
|
|
||||
|
```sh |
||||
|
npx @hey-api/openapi-ts -i ./openapi.json -o src/client |
||||
|
``` |
||||
|
|
||||
|
نیا client بنانے کے بعد، آپ کے پاس اب **صاف method نام** ہوں گے، تمام **autocompletion**، **inline errors** وغیرہ کے ساتھ: |
||||
|
|
||||
|
<img src="/img/tutorial/generate-clients/image08.png"> |
||||
|
|
||||
|
## فوائد { #benefits } |
||||
|
|
||||
|
خود بخود بنائے گئے clients استعمال کرتے وقت آپ کو **autocompletion** ملے گا: |
||||
|
|
||||
|
* Methods کے لیے۔ |
||||
|
* Body میں Request payloads، query parameters وغیرہ کے لیے۔ |
||||
|
* Response payloads کے لیے۔ |
||||
|
|
||||
|
آپ کو ہر چیز کے لیے **inline errors** بھی ملیں گے۔ |
||||
|
|
||||
|
اور جب بھی آپ backend کوڈ اپ ڈیٹ کریں، اور frontend **دوبارہ بنائیں**، اس میں تمام نئی *path operations* methods کے طور پر دستیاب ہوں گی، پرانی ہٹ جائیں گی، اور کوئی بھی تبدیلی بنائے گئے کوڈ میں ظاہر ہوگی۔ |
||||
|
|
||||
|
اس کا مطلب یہ بھی ہے کہ اگر کچھ بدلا تو یہ خود بخود client کوڈ میں **ظاہر** ہوگا۔ اور اگر آپ client **بلڈ** کریں تو اگر استعمال شدہ ڈیٹا میں کوئی **مماثلت نہ ہو** تو غلطی آئے گی۔ |
||||
|
|
||||
|
تو، آپ ترقیاتی عمل میں بہت جلد **بہت سی غلطیاں پکڑ** لیں گے بجائے اس کے کہ غلطیاں پروڈکشن میں آپ کے آخری صارفین کو نظر آئیں اور پھر آپ مسئلے کی تشخیص کرنے کی کوشش کریں۔ |
||||
@ -0,0 +1,21 @@ |
|||||
|
# ایڈوانسڈ صارف گائیڈ { #advanced-user-guide } |
||||
|
|
||||
|
## اضافی خصوصیات { #additional-features } |
||||
|
|
||||
|
بنیادی [ٹیوٹوریل - صارف گائیڈ](../tutorial/index.md) آپ کو **FastAPI** کی تمام اہم خصوصیات کا مکمل جائزہ دینے کے لیے کافی ہونا چاہیے۔ |
||||
|
|
||||
|
آنے والے حصوں میں آپ مزید اختیارات، ترتیبات اور اضافی خصوصیات دیکھیں گے۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
آنے والے حصے **ضروری نہیں کہ "ایڈوانسڈ" ہوں**۔ |
||||
|
|
||||
|
اور یہ ممکن ہے کہ آپ کے استعمال کے لیے حل انہیں میں سے کسی ایک میں ہو۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## پہلے ٹیوٹوریل پڑھیں { #read-the-tutorial-first } |
||||
|
|
||||
|
آپ بنیادی [ٹیوٹوریل - صارف گائیڈ](../tutorial/index.md) کے علم سے **FastAPI** کی زیادہ تر خصوصیات استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
اور آنے والے حصے فرض کرتے ہیں کہ آپ نے اسے پہلے ہی پڑھ لیا ہے، اور یہ فرض کرتے ہیں کہ آپ ان بنیادی تصورات سے واقف ہیں۔ |
||||
@ -0,0 +1,63 @@ |
|||||
|
# Base64 کے طور پر Bytes کے ساتھ JSON { #json-with-bytes-as-base64 } |
||||
|
|
||||
|
اگر آپ کی ایپ کو JSON ڈیٹا وصول اور بھیجنا ہے، لیکن اس میں binary ڈیٹا بھی شامل کرنا ہے، تو آپ اسے base64 کے طور پر encode کر سکتے ہیں۔ |
||||
|
|
||||
|
## Base64 بمقابلہ فائلیں { #base64-vs-files } |
||||
|
|
||||
|
پہلے غور کریں کہ کیا آپ binary ڈیٹا اپ لوڈ کرنے کے لیے [Request Files](../tutorial/request-files.md) اور binary ڈیٹا بھیجنے کے لیے [Custom Response - FileResponse](./custom-response.md#fileresponse--fileresponse-) استعمال کر سکتے ہیں، JSON میں encode کرنے کی بجائے۔ |
||||
|
|
||||
|
JSON صرف UTF-8 encoded strings رکھ سکتا ہے، اس لیے اس میں خام bytes نہیں ہو سکتے۔ |
||||
|
|
||||
|
Base64 binary ڈیٹا کو strings میں encode کر سکتا ہے، لیکن ایسا کرنے کے لیے اسے اصل binary ڈیٹا سے زیادہ characters استعمال کرنے ہوتے ہیں، اس لیے یہ عام طور پر عام فائلوں سے کم موثر ہوتا ہے۔ |
||||
|
|
||||
|
Base64 صرف اسی وقت استعمال کریں جب آپ کو یقینی طور پر JSON میں binary ڈیٹا شامل کرنا ہو، اور آپ اس کے لیے فائلیں استعمال نہیں کر سکتے۔ |
||||
|
|
||||
|
## Pydantic `bytes` { #pydantic-bytes } |
||||
|
|
||||
|
آپ `bytes` fields کے ساتھ Pydantic model بیان کر سکتے ہیں، اور پھر model config میں `val_json_bytes` استعمال کر کے بتا سکتے ہیں کہ input JSON ڈیٹا کو *validate* کرنے کے لیے base64 استعمال کرے، اس validation کے حصے کے طور پر یہ base64 string کو bytes میں decode کرے گا۔ |
||||
|
|
||||
|
{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:9,29:35] hl[9] *} |
||||
|
|
||||
|
اگر آپ `/docs` چیک کریں، تو وہ دکھائیں گے کہ `data` field base64 encoded bytes کی توقع رکھتا ہے: |
||||
|
|
||||
|
<div class="screenshot"> |
||||
|
<img src="/img/tutorial/json-base64-bytes/image01.png"> |
||||
|
</div> |
||||
|
|
||||
|
آپ اس طرح request بھیج سکتے ہیں: |
||||
|
|
||||
|
```json |
||||
|
{ |
||||
|
"description": "Some data", |
||||
|
"data": "aGVsbG8=" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
`aGVsbG8=` `hello` کی base64 encoding ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
اور پھر Pydantic base64 string decode کرے گا اور آپ کو model کے `data` field میں اصل bytes دے گا۔ |
||||
|
|
||||
|
آپ کو اس طرح response ملے گا: |
||||
|
|
||||
|
```json |
||||
|
{ |
||||
|
"description": "Some data", |
||||
|
"content": "hello" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
## آؤٹ پٹ ڈیٹا کے لیے Pydantic `bytes` { #pydantic-bytes-for-output-data } |
||||
|
|
||||
|
آپ آؤٹ پٹ ڈیٹا کے لیے بھی model config میں `ser_json_bytes` کے ساتھ `bytes` fields استعمال کر سکتے ہیں، اور JSON response بناتے وقت Pydantic bytes کو base64 کے طور پر *serialize* کرے گا۔ |
||||
|
|
||||
|
{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,12:16,29,38:41] hl[16] *} |
||||
|
|
||||
|
## ان پٹ اور آؤٹ پٹ ڈیٹا دونوں کے لیے Pydantic `bytes` { #pydantic-bytes-for-input-and-output-data } |
||||
|
|
||||
|
اور یقیناً، آپ JSON ڈیٹا وصول اور بھیجتے وقت `val_json_bytes` سے input (*validate*) اور `ser_json_bytes` سے output (*serialize*) دونوں ہینڈل کرنے کے لیے base64 استعمال کرنے کے لیے ترتیب شدہ وہی model استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,19:26,29,44:46] hl[23:26] *} |
||||
@ -0,0 +1,97 @@ |
|||||
|
# ایڈوانسڈ Middleware { #advanced-middleware } |
||||
|
|
||||
|
بنیادی ٹیوٹوریل میں آپ نے پڑھا کہ اپنی ایپلیکیشن میں [اپنی مرضی کا Middleware](../tutorial/middleware.md) کیسے شامل کریں۔ |
||||
|
|
||||
|
اور پھر آپ نے یہ بھی پڑھا کہ [`CORSMiddleware`](../tutorial/cors.md) سے CORS کو کیسے ہینڈل کریں۔ |
||||
|
|
||||
|
اس سیکشن میں ہم دیکھیں گے کہ دوسرے middleware کیسے استعمال کریں۔ |
||||
|
|
||||
|
## ASGI middleware شامل کرنا { #adding-asgi-middlewares } |
||||
|
|
||||
|
چونکہ **FastAPI** Starlette پر مبنی ہے اور <abbr title="Asynchronous Server Gateway Interface">ASGI</abbr> specification کو لاگو کرتا ہے، آپ کوئی بھی ASGI middleware استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
middleware کا FastAPI یا Starlette کے لیے مخصوص ہونا ضروری نہیں ہے، بس یہ ASGI spec کی پیروی کرے۔ |
||||
|
|
||||
|
عام طور پر، ASGI middleware ایسی classes ہوتی ہیں جو پہلے argument کے طور پر ASGI app وصول کرتی ہیں۔ |
||||
|
|
||||
|
تو، third-party ASGI middleware کی دستاویزات میں وہ شاید آپ کو کچھ اس طرح کرنے کا کہیں گے: |
||||
|
|
||||
|
```Python |
||||
|
from unicorn import UnicornMiddleware |
||||
|
|
||||
|
app = SomeASGIApp() |
||||
|
|
||||
|
new_app = UnicornMiddleware(app, some_config="rainbow") |
||||
|
``` |
||||
|
|
||||
|
لیکن FastAPI (دراصل Starlette) ایسا کرنے کا ایک آسان طریقہ فراہم کرتا ہے جو یقینی بناتا ہے کہ اندرونی middleware server errors اور حسب ضرورت exception handlers کو صحیح طریقے سے ہینڈل کریں۔ |
||||
|
|
||||
|
اس کے لیے، آپ `app.add_middleware()` استعمال کریں (جیسا کہ CORS کی مثال میں)۔ |
||||
|
|
||||
|
```Python |
||||
|
from fastapi import FastAPI |
||||
|
from unicorn import UnicornMiddleware |
||||
|
|
||||
|
app = FastAPI() |
||||
|
|
||||
|
app.add_middleware(UnicornMiddleware, some_config="rainbow") |
||||
|
``` |
||||
|
|
||||
|
`app.add_middleware()` پہلے argument کے طور پر middleware class وصول کرتا ہے اور باقی اضافی arguments middleware کو پاس کر دیے جاتے ہیں۔ |
||||
|
|
||||
|
## شامل middleware { #integrated-middlewares } |
||||
|
|
||||
|
**FastAPI** عام استعمال کے لیے کئی middleware شامل کرتا ہے، آگے ہم دیکھیں گے کہ انہیں کیسے استعمال کریں۔ |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
اگلی مثالوں کے لیے، آپ `from starlette.middleware.something import SomethingMiddleware` بھی استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
**FastAPI** آپ کی سہولت کے لیے `fastapi.middleware` میں کئی middleware فراہم کرتا ہے۔ لیکن زیادہ تر دستیاب middleware براہ راست Starlette سے آتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## `HTTPSRedirectMiddleware` { #httpsredirectmiddleware } |
||||
|
|
||||
|
یہ لازم کرتا ہے کہ تمام آنے والی requests `https` یا `wss` ہوں۔ |
||||
|
|
||||
|
`http` یا `ws` پر آنے والی کسی بھی request کو محفوظ scheme کی طرف redirect کر دیا جائے گا۔ |
||||
|
|
||||
|
{* ../../docs_src/advanced_middleware/tutorial001_py310.py hl[2,6] *} |
||||
|
|
||||
|
## `TrustedHostMiddleware` { #trustedhostmiddleware } |
||||
|
|
||||
|
یہ لازم کرتا ہے کہ تمام آنے والی requests میں `Host` header درست طریقے سے سیٹ ہو، تاکہ HTTP Host Header حملوں سے بچا جا سکے۔ |
||||
|
|
||||
|
{* ../../docs_src/advanced_middleware/tutorial002_py310.py hl[2,6:8] *} |
||||
|
|
||||
|
درج ذیل arguments سپورٹ ہوتے ہیں: |
||||
|
|
||||
|
* `allowed_hosts` - ان domain ناموں کی فہرست جنہیں hostname کے طور پر اجازت ہونی چاہیے۔ Wildcard domains جیسے `*.example.com` subdomains کی matching کے لیے سپورٹ ہوتے ہیں۔ کسی بھی hostname کو اجازت دینے کے لیے `allowed_hosts=["*"]` استعمال کریں یا middleware کو چھوڑ دیں۔ |
||||
|
* `www_redirect` - اگر True پر سیٹ ہو تو، اجازت یافتہ hosts کے غیر www ورژنز کی requests ان کے www ہم منصبوں کی طرف redirect ہو جائیں گی۔ بطور ڈیفالٹ `True` ہے۔ |
||||
|
|
||||
|
اگر آنے والی request درست طریقے سے validate نہیں ہوتی تو `400` response بھیجا جائے گا۔ |
||||
|
|
||||
|
## `GZipMiddleware` { #gzipmiddleware } |
||||
|
|
||||
|
GZip responses کو ہینڈل کرتا ہے ہر اس request کے لیے جس کے `Accept-Encoding` header میں `"gzip"` شامل ہو۔ |
||||
|
|
||||
|
یہ middleware معیاری اور streaming دونوں قسم کے responses کو ہینڈل کرے گا۔ |
||||
|
|
||||
|
{* ../../docs_src/advanced_middleware/tutorial003_py310.py hl[2,6] *} |
||||
|
|
||||
|
درج ذیل arguments سپورٹ ہوتے ہیں: |
||||
|
|
||||
|
* `minimum_size` - اس کم از کم سائز (bytes میں) سے چھوٹے responses کو GZip نہ کریں۔ بطور ڈیفالٹ `500` ہے۔ |
||||
|
* `compresslevel` - GZip compression کے دوران استعمال ہوتا ہے۔ یہ 1 سے 9 تک کا integer ہے۔ بطور ڈیفالٹ `9` ہے۔ کم قدر تیز compression لیکن بڑے فائل سائز کا نتیجہ ہے، جبکہ زیادہ قدر سست compression لیکن چھوٹے فائل سائز کا نتیجہ ہے۔ |
||||
|
|
||||
|
## دوسرے middleware { #other-middlewares } |
||||
|
|
||||
|
بہت سے دوسرے ASGI middleware موجود ہیں۔ |
||||
|
|
||||
|
مثال کے طور پر: |
||||
|
|
||||
|
* [Uvicorn کا `ProxyHeadersMiddleware`](https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py) |
||||
|
* [MessagePack](https://github.com/florimondmanca/msgpack-asgi) |
||||
|
|
||||
|
دوسرے دستیاب middleware دیکھنے کے لیے [Starlette کی Middleware دستاویزات](https://www.starlette.dev/middleware/) اور [ASGI Awesome List](https://github.com/florimondmanca/awesome-asgi) دیکھیں۔ |
||||
@ -0,0 +1,186 @@ |
|||||
|
# OpenAPI Callbacks { #openapi-callbacks } |
||||
|
|
||||
|
آپ ایک ایسا API بنا سکتے ہیں جس میں *path operation* کسی *بیرونی API* کو request بھیجنے کا عمل شروع کرے جو کسی اور نے بنایا ہو (شاید وہی ڈویلپر جو آپ کا API *استعمال* کر رہا ہو)۔ |
||||
|
|
||||
|
جب آپ کا API ایپ *بیرونی API* کو کال کرتا ہے تو اس عمل کو "callback" کہتے ہیں۔ کیونکہ بیرونی ڈویلپر کا سافٹ ویئر آپ کے API کو request بھیجتا ہے اور پھر آپ کا API *واپس کال کرتا ہے*، *بیرونی API* کو request بھیج کر (جو شاید اسی ڈویلپر نے بنایا ہو)۔ |
||||
|
|
||||
|
اس صورت میں، آپ یہ دستاویز کرنا چاہیں گے کہ وہ بیرونی API *کیسا* ہونا چاہیے۔ اس کی *path operation* کیا ہونی چاہیے، اسے کیا body توقع کرنا چاہیے، کیا response واپس کرنا چاہیے، وغیرہ۔ |
||||
|
|
||||
|
## Callbacks والی ایپ { #an-app-with-callbacks } |
||||
|
|
||||
|
آئیے یہ سب ایک مثال سے دیکھتے ہیں۔ |
||||
|
|
||||
|
فرض کریں آپ ایک ایسی ایپ بناتے ہیں جو invoices بنانے کی اجازت دیتی ہے۔ |
||||
|
|
||||
|
ان invoices میں `id`، `title` (اختیاری)، `customer`، اور `total` ہوگا۔ |
||||
|
|
||||
|
آپ کے API کا صارف (بیرونی ڈویلپر) آپ کے API میں POST request کے ساتھ invoice بنائے گا۔ |
||||
|
|
||||
|
پھر آپ کا API (فرض کریں): |
||||
|
|
||||
|
* بیرونی ڈویلپر کے کسی کسٹمر کو invoice بھیجے گا۔ |
||||
|
* رقم وصول کرے گا۔ |
||||
|
* API صارف (بیرونی ڈویلپر) کو واپس اطلاع بھیجے گا۔ |
||||
|
* یہ (*آپ کے API* سے) بیرونی ڈویلپر کی فراہم کردہ *بیرونی API* کو POST request بھیج کر کیا جائے گا (یہ "callback" ہے)۔ |
||||
|
|
||||
|
## عام **FastAPI** ایپ { #the-normal-fastapi-app } |
||||
|
|
||||
|
آئیے پہلے دیکھیں کہ callback شامل کرنے سے پہلے عام API ایپ کیسی ہوگی۔ |
||||
|
|
||||
|
اس میں ایک *path operation* ہوگی جو `Invoice` body وصول کرے گی، اور ایک query parameter `callback_url` جس میں callback کا URL ہوگا۔ |
||||
|
|
||||
|
یہ حصہ کافی عام ہے، زیادہ تر کوڈ شاید آپ کو پہلے سے مانوس ہوگا: |
||||
|
|
||||
|
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[7:11,34:51] *} |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
`callback_url` query parameter Pydantic [Url](https://docs.pydantic.dev/latest/api/networks/) قسم استعمال کرتا ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
واحد نئی چیز `callbacks=invoices_callback_router.routes` ہے بطور *path operation decorator* کے argument۔ ہم اگلے حصے میں دیکھیں گے کہ یہ کیا ہے۔ |
||||
|
|
||||
|
## Callback کی دستاویزات { #documenting-the-callback } |
||||
|
|
||||
|
اصل callback کوڈ آپ کی اپنی API ایپ پر بہت زیادہ منحصر ہوگا۔ |
||||
|
|
||||
|
اور یہ شاید ایک ایپ سے دوسری تک بہت مختلف ہوگا۔ |
||||
|
|
||||
|
یہ صرف ایک یا دو لائنیں کوڈ ہو سکتی ہیں، جیسے: |
||||
|
|
||||
|
```Python |
||||
|
callback_url = "https://example.com/api/v1/invoices/events/" |
||||
|
httpx.post(callback_url, json={"description": "Invoice paid", "paid": True}) |
||||
|
``` |
||||
|
|
||||
|
لیکن شاید callback کا سب سے اہم حصہ یہ یقینی بنانا ہے کہ آپ کے API صارف (بیرونی ڈویلپر) *بیرونی API* کو درست طریقے سے بنائیں، اس ڈیٹا کے مطابق جو *آپ کا API* callback کی request body میں بھیجے گا، وغیرہ۔ |
||||
|
|
||||
|
تو، اگلا ہم وہ کوڈ شامل کریں گے جو دستاویز کرے کہ وہ *بیرونی API* *آپ کے API* سے callback وصول کرنے کے لیے کیسی ہونی چاہیے۔ |
||||
|
|
||||
|
وہ دستاویزات آپ کے API میں `/docs` پر Swagger UI میں نظر آئیں گی، اور بیرونی ڈویلپرز کو بتائیں گی کہ *بیرونی API* کیسے بنائیں۔ |
||||
|
|
||||
|
یہ مثال خود callback لاگو نہیں کرتی (وہ صرف کوڈ کی ایک لائن ہو سکتا ہے)، صرف دستاویزات والا حصہ۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
اصل callback صرف ایک HTTP request ہے۔ |
||||
|
|
||||
|
خود callback لاگو کرتے وقت، آپ [HTTPX](https://www.python-httpx.org) یا [Requests](https://requests.readthedocs.io/) جیسی کوئی چیز استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Callback دستاویزات کا کوڈ لکھیں { #write-the-callback-documentation-code } |
||||
|
|
||||
|
یہ کوڈ آپ کی ایپ میں عمل میں نہیں آئے گا، ہمیں اس کی صرف اس *بیرونی API* کی دستاویزات کے لیے ضرورت ہے۔ |
||||
|
|
||||
|
لیکن، آپ پہلے سے جانتے ہیں کہ **FastAPI** کے ساتھ API کے لیے خودکار دستاویزات آسانی سے کیسے بنائیں۔ |
||||
|
|
||||
|
تو ہم اسی علم کو استعمال کرتے ہوئے دستاویز کریں گے کہ *بیرونی API* کیسی ہونی چاہیے... وہ *path operation(s)* بنا کر جو بیرونی API کو لاگو کرنی چاہییں (جنہیں آپ کا API کال کرے گا)۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
callback کی دستاویزات کا کوڈ لکھتے وقت، یہ تصور کرنا مفید ہو سکتا ہے کہ آپ وہ *بیرونی ڈویلپر* ہیں۔ اور آپ اس وقت *بیرونی API* لاگو کر رہے ہیں، نہ کہ *آپ کا API*۔ |
||||
|
|
||||
|
عارضی طور پر یہ نقطہ نظر (*بیرونی ڈویلپر* کا) اپنانے سے آپ کو یہ زیادہ واضح محسوس ہو سکتا ہے کہ اس *بیرونی API* کے لیے parameters، Pydantic model body کے لیے، response کے لیے، وغیرہ کہاں رکھیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### Callback `APIRouter` بنائیں { #create-a-callback-apirouter } |
||||
|
|
||||
|
سب سے پہلے ایک نیا `APIRouter` بنائیں جس میں ایک یا زیادہ callbacks ہوں۔ |
||||
|
|
||||
|
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[1,23] *} |
||||
|
|
||||
|
### Callback *path operation* بنائیں { #create-the-callback-path-operation } |
||||
|
|
||||
|
callback *path operation* بنانے کے لیے اوپر بنایا گیا وہی `APIRouter` استعمال کریں۔ |
||||
|
|
||||
|
یہ عام FastAPI *path operation* جیسا ہی ہونا چاہیے: |
||||
|
|
||||
|
* اس میں شاید body کی بیان ہونی چاہیے جو اسے وصول کرنا ہے، مثلاً `body: InvoiceEvent`۔ |
||||
|
* اور اس میں response کی بیان بھی ہو سکتی ہے جو اسے واپس کرنا چاہیے، مثلاً `response_model=InvoiceEventReceived`۔ |
||||
|
|
||||
|
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[14:16,19:20,26:30] *} |
||||
|
|
||||
|
عام *path operation* سے 2 اہم فرق ہیں: |
||||
|
|
||||
|
* اس میں کوئی اصل کوڈ ہونے کی ضرورت نہیں، کیونکہ آپ کی ایپ کبھی یہ کوڈ نہیں بلائے گی۔ یہ صرف *بیرونی API* کی دستاویزات کے لیے استعمال ہوتا ہے۔ تو، function میں صرف `pass` ہو سکتا ہے۔ |
||||
|
* *path* میں [OpenAPI 3 expression](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression) ہو سکتا ہے (نیچے مزید دیکھیں) جہاں یہ *آپ کے API* کو بھیجی گئی اصل request کے parameters اور حصوں سے variables استعمال کر سکتا ہے۔ |
||||
|
|
||||
|
### Callback path expression { #the-callback-path-expression } |
||||
|
|
||||
|
callback *path* میں [OpenAPI 3 expression](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression) ہو سکتا ہے جس میں *آپ کے API* کو بھیجی گئی اصل request کے حصے شامل ہوں۔ |
||||
|
|
||||
|
اس صورت میں، یہ `str` ہے: |
||||
|
|
||||
|
```Python |
||||
|
"{$callback_url}/invoices/{$request.body.id}" |
||||
|
``` |
||||
|
|
||||
|
تو، اگر آپ کے API کا صارف (بیرونی ڈویلپر) *آپ کے API* کو اس پر request بھیجے: |
||||
|
|
||||
|
``` |
||||
|
https://yourapi.com/invoices/?callback_url=https://www.external.org/events |
||||
|
``` |
||||
|
|
||||
|
JSON body کے ساتھ: |
||||
|
|
||||
|
```JSON |
||||
|
{ |
||||
|
"id": "2expen51ve", |
||||
|
"customer": "Mr. Richie Rich", |
||||
|
"total": "9999" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
تو پھر *آپ کا API* invoice پروسیس کرے گا، اور کچھ وقت بعد، callback request `callback_url` (وہ *بیرونی API*) کو بھیجے گا: |
||||
|
|
||||
|
``` |
||||
|
https://www.external.org/events/invoices/2expen51ve |
||||
|
``` |
||||
|
|
||||
|
JSON body کے ساتھ جس میں کچھ ایسا ہوگا: |
||||
|
|
||||
|
```JSON |
||||
|
{ |
||||
|
"description": "Payment celebration", |
||||
|
"paid": true |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
اور یہ اس *بیرونی API* سے JSON body کے ساتھ اس طرح کا response توقع کرے گا: |
||||
|
|
||||
|
```JSON |
||||
|
{ |
||||
|
"ok": true |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
غور کریں کہ callback URL میں query parameter `callback_url` میں وصول شدہ URL (`https://www.external.org/events`) اور JSON body کے اندر سے invoice `id` (`2expen51ve`) دونوں شامل ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### Callback router شامل کریں { #add-the-callback-router } |
||||
|
|
||||
|
اس مقام پر آپ کے پاس اوپر بنائے گئے callback router میں ضروری *callback path operation(s)* موجود ہیں (جو *بیرونی ڈویلپر* کو *بیرونی API* میں لاگو کرنی چاہییں)۔ |
||||
|
|
||||
|
اب *آپ کے API کے path operation decorator* میں `callbacks` parameter استعمال کریں اور اس callback router سے attribute `.routes` (جو دراصل routes/*path operations* کی `list` ہے) پاس کریں: |
||||
|
|
||||
|
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *} |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
غور کریں کہ آپ خود router (`invoices_callback_router`) کو `callback=` میں پاس نہیں کر رہے، بلکہ attribute `.routes`، یعنی `invoices_callback_router.routes` پاس کر رہے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### Docs چیک کریں { #check-the-docs } |
||||
|
|
||||
|
اب آپ اپنی ایپ شروع کر سکتے ہیں اور [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) پر جائیں۔ |
||||
|
|
||||
|
آپ کو اپنے docs میں اپنی *path operation* کے لیے "Callbacks" سیکشن نظر آئے گا جو دکھائے گا کہ *بیرونی API* کیسی ہونی چاہیے: |
||||
|
|
||||
|
<img src="/img/tutorial/openapi-callbacks/image01.png"> |
||||
@ -0,0 +1,55 @@ |
|||||
|
# OpenAPI Webhooks { #openapi-webhooks } |
||||
|
|
||||
|
ایسی صورتیں ہوتی ہیں جہاں آپ اپنے API **صارفین** کو بتانا چاہتے ہیں کہ آپ کی ایپ *ان کی* ایپ کو (request بھیج کر) کچھ ڈیٹا بھیج سکتی ہے، عام طور پر کسی قسم کے **واقعے** کی **اطلاع** دینے کے لیے۔ |
||||
|
|
||||
|
اس کا مطلب ہے کہ عام عمل کی بجائے جہاں آپ کے صارفین آپ کے API کو requests بھیجتے ہیں، یہاں **آپ کا API** (یا آپ کی ایپ) **ان کے سسٹم** (ان کے API، ان کی ایپ) کو **requests بھیج** سکتا ہے۔ |
||||
|
|
||||
|
اسے عام طور پر **webhook** کہتے ہیں۔ |
||||
|
|
||||
|
## Webhooks کے مراحل { #webhooks-steps } |
||||
|
|
||||
|
عمل عام طور پر یہ ہوتا ہے کہ **آپ بیان کرتے ہیں** اپنے کوڈ میں کہ وہ پیغام کیا ہوگا جو آپ بھیجیں گے، request کی **body**۔ |
||||
|
|
||||
|
آپ کسی طریقے سے یہ بھی بیان کرتے ہیں کہ آپ کی ایپ وہ requests یا events **کن لمحات** پر بھیجے گی۔ |
||||
|
|
||||
|
اور **آپ کے صارفین** کسی طریقے سے (مثلاً کہیں ویب dashboard میں) وہ **URL** بیان کرتے ہیں جہاں آپ کی ایپ کو وہ requests بھیجنی چاہییں۔ |
||||
|
|
||||
|
webhooks کے لیے URLs رجسٹر کرنے کی **منطق** اور requests بھیجنے کا اصل کوڈ آپ پر ہے۔ آپ اسے اپنے **کوڈ** میں جیسے چاہیں لکھتے ہیں۔ |
||||
|
|
||||
|
## **FastAPI** اور OpenAPI کے ساتھ webhooks دستاویز کرنا { #documenting-webhooks-with-fastapi-and-openapi } |
||||
|
|
||||
|
**FastAPI** کے ساتھ، OpenAPI استعمال کرتے ہوئے، آپ ان webhooks کے نام، HTTP operations کی اقسام جو آپ کی ایپ بھیج سکتی ہے (مثلاً `POST`، `PUT` وغیرہ) اور request **bodies** جو آپ کی ایپ بھیجے گی، بیان کر سکتے ہیں۔ |
||||
|
|
||||
|
اس سے آپ کے صارفین کے لیے آپ کی **webhook** requests وصول کرنے کے لیے **اپنے APIs بنانا** بہت آسان ہو سکتا ہے، وہ شاید اپنا API کوڈ خود بخود بنانے کے بھی قابل ہوں۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
Webhooks OpenAPI 3.1.0 اور اس سے اوپر میں دستیاب ہیں، FastAPI `0.99.0` اور اس سے اوپر میں سپورٹ ہوتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Webhooks والی ایپ { #an-app-with-webhooks } |
||||
|
|
||||
|
جب آپ **FastAPI** ایپلیکیشن بناتے ہیں، تو ایک `webhooks` attribute ہوتا ہے جسے آپ *webhooks* بیان کرنے کے لیے استعمال کر سکتے ہیں، بالکل اسی طرح جیسے آپ *path operations* بیان کرتے ہیں، مثلاً `@app.webhooks.post()` کے ساتھ۔ |
||||
|
|
||||
|
{* ../../docs_src/openapi_webhooks/tutorial001_py310.py hl[9:12,15:20] *} |
||||
|
|
||||
|
آپ جو webhooks بیان کریں گے وہ **OpenAPI** schema اور خودکار **docs UI** میں نظر آئیں گے۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
`app.webhooks` آبجیکٹ دراصل ایک `APIRouter` ہے، وہی قسم جو آپ اپنی ایپ کو متعدد فائلوں سے ترتیب دیتے وقت استعمال کرتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
غور کریں کہ webhooks کے ساتھ آپ دراصل *path* (جیسے `/items/`) بیان نہیں کر رہے، وہاں جو ٹیکسٹ آپ پاس کرتے ہیں وہ صرف webhook کا **شناختی نام** (event کا نام) ہے، مثلاً `@app.webhooks.post("new-subscription")` میں، webhook کا نام `new-subscription` ہے۔ |
||||
|
|
||||
|
اس کی وجہ یہ ہے کہ یہ توقع کی جاتی ہے کہ **آپ کے صارفین** اصل **URL path** کسی اور طریقے سے بیان کریں گے جہاں وہ webhook request وصول کرنا چاہتے ہیں (مثلاً ویب dashboard)۔ |
||||
|
|
||||
|
### Docs چیک کریں { #check-the-docs } |
||||
|
|
||||
|
اب آپ اپنی ایپ شروع کر سکتے ہیں اور [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) پر جائیں۔ |
||||
|
|
||||
|
آپ دیکھیں گے کہ آپ کے docs میں عام *path operations* اور کچھ **webhooks** بھی ہیں: |
||||
|
|
||||
|
<img src="/img/tutorial/openapi-webhooks/image01.png"> |
||||
@ -0,0 +1,172 @@ |
|||||
|
# Path Operation ایڈوانسڈ ترتیب { #path-operation-advanced-configuration } |
||||
|
|
||||
|
## OpenAPI operationId { #openapi-operationid } |
||||
|
|
||||
|
/// warning | انتباہ |
||||
|
|
||||
|
اگر آپ OpenAPI میں "ماہر" نہیں ہیں، تو آپ کو شاید اس کی ضرورت نہ ہو۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
آپ اپنے *path operation* میں `operation_id` parameter استعمال کر کے OpenAPI `operationId` مقرر کر سکتے ہیں۔ |
||||
|
|
||||
|
آپ کو یقینی بنانا ہوگا کہ یہ ہر operation کے لیے منفرد ہو۔ |
||||
|
|
||||
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py310.py hl[6] *} |
||||
|
|
||||
|
### *path operation function* کا نام بطور operationId استعمال کرنا { #using-the-path-operation-function-name-as-the-operationid } |
||||
|
|
||||
|
اگر آپ اپنے APIs کے function ناموں کو `operationId` کے طور پر استعمال کرنا چاہتے ہیں، تو آپ ان سب پر iterate کر سکتے ہیں اور ہر *path operation* کے `operation_id` کو ان کے `APIRoute.name` سے تبدیل کر سکتے ہیں۔ |
||||
|
|
||||
|
آپ کو یہ اپنے تمام *path operations* شامل کرنے کے بعد کرنا چاہیے۔ |
||||
|
|
||||
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2, 12:21, 24] *} |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
اگر آپ دستی طور پر `app.openapi()` کال کرتے ہیں، تو آپ کو اس سے پہلے `operationId` اپ ڈیٹ کرنے چاہئیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// warning | انتباہ |
||||
|
|
||||
|
اگر آپ ایسا کرتے ہیں، تو آپ کو یقینی بنانا ہوگا کہ آپ کے ہر *path operation function* کا نام منفرد ہو۔ |
||||
|
|
||||
|
چاہے وہ مختلف modules (Python فائلوں) میں ہوں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## OpenAPI سے خارج کریں { #exclude-from-openapi } |
||||
|
|
||||
|
کسی *path operation* کو تیار شدہ OpenAPI schema سے (اور اس طرح خودکار دستاویزی نظاموں سے) خارج کرنے کے لیے، parameter `include_in_schema` استعمال کریں اور اسے `False` پر مقرر کریں: |
||||
|
|
||||
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py310.py hl[6] *} |
||||
|
|
||||
|
## docstring سے ایڈوانسڈ وضاحت { #advanced-description-from-docstring } |
||||
|
|
||||
|
آپ *path operation function* کے docstring سے OpenAPI کے لیے استعمال ہونے والی سطروں کو محدود کر سکتے ہیں۔ |
||||
|
|
||||
|
`\f` (ایک escaped "form feed" حرف) شامل کرنے سے **FastAPI** اس مقام پر OpenAPI کے لیے استعمال ہونے والی آؤٹ پٹ کو تراش دے گا۔ |
||||
|
|
||||
|
یہ دستاویزات میں نظر نہیں آئے گا، لیکن دوسرے ٹولز (جیسے Sphinx) باقی حصہ استعمال کر سکیں گے۔ |
||||
|
|
||||
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *} |
||||
|
|
||||
|
## اضافی Responses { #additional-responses } |
||||
|
|
||||
|
آپ نے شاید دیکھا ہوگا کہ *path operation* کے لیے `response_model` اور `status_code` کا اعلان کیسے کیا جاتا ہے۔ |
||||
|
|
||||
|
یہ *path operation* کے بنیادی response کے بارے میں metadata بیان کرتا ہے۔ |
||||
|
|
||||
|
آپ اضافی responses بھی اعلان کر سکتے ہیں ان کے models، status codes وغیرہ کے ساتھ۔ |
||||
|
|
||||
|
دستاویزات میں اس بارے میں ایک مکمل باب ہے، آپ اسے [OpenAPI میں اضافی Responses](additional-responses.md) پر پڑھ سکتے ہیں۔ |
||||
|
|
||||
|
## OpenAPI Extra { #openapi-extra } |
||||
|
|
||||
|
جب آپ اپنی ایپلیکیشن میں *path operation* کا اعلان کرتے ہیں، **FastAPI** خود بخود اس *path operation* کے بارے میں متعلقہ metadata تیار کرتا ہے تاکہ اسے OpenAPI schema میں شامل کیا جا سکے۔ |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
OpenAPI specification میں اسے [Operation Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object) کہا جاتا ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
اس میں *path operation* کے بارے میں تمام معلومات ہوتی ہیں اور اسے خودکار دستاویزات تیار کرنے کے لیے استعمال کیا جاتا ہے۔ |
||||
|
|
||||
|
اس میں `tags`، `parameters`، `requestBody`، `responses` وغیرہ شامل ہیں۔ |
||||
|
|
||||
|
یہ *path operation* مخصوص OpenAPI schema عام طور پر **FastAPI** کی طرف سے خود بخود تیار ہوتا ہے، لیکن آپ اسے بڑھا بھی سکتے ہیں۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
یہ ایک نچلی سطح کا extension point ہے۔ |
||||
|
|
||||
|
اگر آپ کو صرف اضافی responses کا اعلان کرنا ہے، تو اس کا ایک زیادہ آسان طریقہ [OpenAPI میں اضافی Responses](additional-responses.md) ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
آپ `openapi_extra` parameter استعمال کر کے *path operation* کے OpenAPI schema کو بڑھا سکتے ہیں۔ |
||||
|
|
||||
|
### OpenAPI Extensions { #openapi-extensions } |
||||
|
|
||||
|
یہ `openapi_extra` مفید ہو سکتا ہے، مثال کے طور پر، [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions) کا اعلان کرنے کے لیے: |
||||
|
|
||||
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py310.py hl[6] *} |
||||
|
|
||||
|
اگر آپ خودکار API docs کھولتے ہیں، تو آپ کی extension مخصوص *path operation* کے نیچے ظاہر ہوگی۔ |
||||
|
|
||||
|
<img src="/img/tutorial/path-operation-advanced-configuration/image01.png"> |
||||
|
|
||||
|
اور اگر آپ نتیجے میں آنے والا OpenAPI دیکھتے ہیں (آپ کے API میں `/openapi.json` پر)، تو آپ اپنی extension مخصوص *path operation* کے حصے کے طور پر بھی دیکھیں گے: |
||||
|
|
||||
|
```JSON hl_lines="22" |
||||
|
{ |
||||
|
"openapi": "3.1.0", |
||||
|
"info": { |
||||
|
"title": "FastAPI", |
||||
|
"version": "0.1.0" |
||||
|
}, |
||||
|
"paths": { |
||||
|
"/items/": { |
||||
|
"get": { |
||||
|
"summary": "Read Items", |
||||
|
"operationId": "read_items_items__get", |
||||
|
"responses": { |
||||
|
"200": { |
||||
|
"description": "Successful Response", |
||||
|
"content": { |
||||
|
"application/json": { |
||||
|
"schema": {} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"x-aperture-labs-portal": "blue" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
### حسب ضرورت OpenAPI *path operation* schema { #custom-openapi-path-operation-schema } |
||||
|
|
||||
|
`openapi_extra` میں موجود dictionary کو *path operation* کے خود بخود تیار شدہ OpenAPI schema کے ساتھ گہرائی سے merge کیا جائے گا۔ |
||||
|
|
||||
|
لہذا، آپ خود بخود تیار شدہ schema میں اضافی ڈیٹا شامل کر سکتے ہیں۔ |
||||
|
|
||||
|
مثال کے طور پر، آپ فیصلہ کر سکتے ہیں کہ request کو اپنے کوڈ سے پڑھیں اور توثیق کریں، Pydantic کے ساتھ FastAPI کی خودکار خصوصیات استعمال کیے بغیر، لیکن آپ پھر بھی OpenAPI schema میں request کی تعریف کرنا چاہیں۔ |
||||
|
|
||||
|
آپ یہ `openapi_extra` کے ساتھ کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py310.py hl[19:36, 39:40] *} |
||||
|
|
||||
|
اس مثال میں، ہم نے کوئی Pydantic model اعلان نہیں کیا۔ دراصل، request body کو JSON کے طور پر <dfn title="converted from some plain format, like bytes, into Python objects">parse</dfn> بھی نہیں کیا گیا، اسے براہ راست `bytes` کے طور پر پڑھا گیا ہے، اور function `magic_data_reader()` اسے کسی طرح parse کرنے کا ذمہ دار ہوگا۔ |
||||
|
|
||||
|
بہرحال، ہم request body کے لیے متوقع schema کا اعلان کر سکتے ہیں۔ |
||||
|
|
||||
|
### حسب ضرورت OpenAPI content type { #custom-openapi-content-type } |
||||
|
|
||||
|
اسی چال کا استعمال کرتے ہوئے، آپ Pydantic model استعمال کر کے JSON Schema بیان کر سکتے ہیں جو پھر *path operation* کے حسب ضرورت OpenAPI schema حصے میں شامل ہوتا ہے۔ |
||||
|
|
||||
|
اور آپ یہ اس صورت میں بھی کر سکتے ہیں جب request میں ڈیٹا کی قسم JSON نہ ہو۔ |
||||
|
|
||||
|
مثال کے طور پر، اس ایپلیکیشن میں ہم FastAPI کی مربوط فعالیت استعمال نہیں کرتے Pydantic models سے JSON Schema نکالنے یا JSON کے لیے خودکار توثیق کے لیے۔ دراصل، ہم request content type کو JSON کی بجائے YAML بیان کر رہے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[15:20, 22] *} |
||||
|
|
||||
|
بہرحال، اگرچہ ہم پہلے سے طے شدہ مربوط فعالیت استعمال نہیں کر رہے، ہم پھر بھی Pydantic model استعمال کر رہے ہیں تاکہ دستی طور پر اس ڈیٹا کے لیے JSON Schema تیار کیا جا سکے جو ہم YAML میں وصول کرنا چاہتے ہیں۔ |
||||
|
|
||||
|
پھر ہم request کو براہ راست استعمال کرتے ہیں، اور body کو `bytes` کے طور پر نکالتے ہیں۔ اس کا مطلب ہے کہ FastAPI request payload کو JSON کے طور پر parse کرنے کی کوشش بھی نہیں کرے گا۔ |
||||
|
|
||||
|
اور پھر اپنے کوڈ میں، ہم اس YAML مواد کو براہ راست parse کرتے ہیں، اور پھر ہم دوبارہ وہی Pydantic model استعمال کر کے YAML مواد کی توثیق کرتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[24:31] *} |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
یہاں ہم وہی Pydantic model دوبارہ استعمال کر رہے ہیں۔ |
||||
|
|
||||
|
لیکن اسی طرح، ہم اسے کسی اور طریقے سے بھی توثیق کر سکتے تھے۔ |
||||
|
|
||||
|
/// |
||||
@ -0,0 +1,31 @@ |
|||||
|
# Response - Status Code تبدیل کریں { #response-change-status-code } |
||||
|
|
||||
|
آپ نے شاید پہلے پڑھا ہوگا کہ آپ پہلے سے طے شدہ [Response Status Code](../tutorial/response-status-code.md) مقرر کر سکتے ہیں۔ |
||||
|
|
||||
|
لیکن بعض صورتوں میں آپ کو پہلے سے طے شدہ status code سے مختلف status code واپس کرنے کی ضرورت ہوتی ہے۔ |
||||
|
|
||||
|
## استعمال کی صورت { #use-case } |
||||
|
|
||||
|
مثال کے طور پر، تصور کریں کہ آپ پہلے سے طے شدہ طور پر HTTP status code "OK" `200` واپس کرنا چاہتے ہیں۔ |
||||
|
|
||||
|
لیکن اگر ڈیٹا موجود نہیں تھا، تو آپ اسے بنانا چاہتے ہیں، اور HTTP status code "CREATED" `201` واپس کرنا چاہتے ہیں۔ |
||||
|
|
||||
|
لیکن آپ پھر بھی `response_model` کے ساتھ واپس کیے گئے ڈیٹا کو فلٹر اور تبدیل کرنے کے قابل رہنا چاہتے ہیں۔ |
||||
|
|
||||
|
ان صورتوں میں، آپ `Response` parameter استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
## `Response` parameter استعمال کریں { #use-a-response-parameter } |
||||
|
|
||||
|
آپ اپنے *path operation function* میں `Response` قسم کا parameter اعلان کر سکتے ہیں (جیسا کہ آپ cookies اور headers کے لیے کر سکتے ہیں)۔ |
||||
|
|
||||
|
اور پھر آپ اس *عارضی* response آبجیکٹ میں `status_code` مقرر کر سکتے ہیں۔ |
||||
|
|
||||
|
{* ../../docs_src/response_change_status_code/tutorial001_py310.py hl[1,9,12] *} |
||||
|
|
||||
|
اور پھر آپ جیسے عام طور پر کرتے ہیں، کوئی بھی آبجیکٹ واپس کر سکتے ہیں (ایک `dict`، database model وغیرہ)۔ |
||||
|
|
||||
|
اور اگر آپ نے `response_model` کا اعلان کیا ہے، تو اسے پھر بھی آپ کے واپس کردہ آبجیکٹ کو فلٹر اور تبدیل کرنے کے لیے استعمال کیا جائے گا۔ |
||||
|
|
||||
|
**FastAPI** اس *عارضی* response کو status code (نیز cookies اور headers) نکالنے کے لیے استعمال کرے گا، اور انہیں حتمی response میں ڈالے گا جس میں آپ کی واپس کردہ قدر ہوگی، کسی بھی `response_model` سے فلٹر شدہ۔ |
||||
|
|
||||
|
آپ dependencies میں بھی `Response` parameter کا اعلان کر سکتے ہیں، اور ان میں status code مقرر کر سکتے ہیں۔ لیکن ذہن میں رکھیں کہ آخری مقرر کیا گیا غالب آئے گا۔ |
||||
@ -0,0 +1,51 @@ |
|||||
|
# Response Cookies { #response-cookies } |
||||
|
|
||||
|
## `Response` parameter استعمال کریں { #use-a-response-parameter } |
||||
|
|
||||
|
آپ اپنے *path operation function* میں `Response` قسم کا parameter اعلان کر سکتے ہیں۔ |
||||
|
|
||||
|
اور پھر آپ اس *عارضی* response آبجیکٹ میں cookies مقرر کر سکتے ہیں۔ |
||||
|
|
||||
|
{* ../../docs_src/response_cookies/tutorial002_py310.py hl[1, 8:9] *} |
||||
|
|
||||
|
اور پھر آپ جیسے عام طور پر کرتے ہیں، کوئی بھی آبجیکٹ واپس کر سکتے ہیں (ایک `dict`، database model وغیرہ)۔ |
||||
|
|
||||
|
اور اگر آپ نے `response_model` کا اعلان کیا ہے، تو اسے پھر بھی آپ کے واپس کردہ آبجیکٹ کو فلٹر اور تبدیل کرنے کے لیے استعمال کیا جائے گا۔ |
||||
|
|
||||
|
**FastAPI** اس *عارضی* response کو cookies (نیز headers اور status code) نکالنے کے لیے استعمال کرے گا، اور انہیں حتمی response میں ڈالے گا جس میں آپ کی واپس کردہ قدر ہوگی، کسی بھی `response_model` سے فلٹر شدہ۔ |
||||
|
|
||||
|
آپ dependencies میں بھی `Response` parameter کا اعلان کر سکتے ہیں، اور ان میں cookies (اور headers) مقرر کر سکتے ہیں۔ |
||||
|
|
||||
|
## براہ راست `Response` واپس کریں { #return-a-response-directly } |
||||
|
|
||||
|
آپ اپنے کوڈ میں براہ راست `Response` واپس کرتے وقت بھی cookies بنا سکتے ہیں۔ |
||||
|
|
||||
|
ایسا کرنے کے لیے، آپ [براہ راست Response واپس کریں](response-directly.md) میں بیان کردہ طریقے سے response بنا سکتے ہیں۔ |
||||
|
|
||||
|
پھر اس میں Cookies مقرر کریں، اور پھر اسے واپس کریں: |
||||
|
|
||||
|
{* ../../docs_src/response_cookies/tutorial001_py310.py hl[10:12] *} |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
ذہن میں رکھیں کہ اگر آپ `Response` parameter استعمال کرنے کی بجائے براہ راست response واپس کرتے ہیں، تو FastAPI اسے براہ راست واپس کرے گا۔ |
||||
|
|
||||
|
لہذا، آپ کو یقینی بنانا ہوگا کہ آپ کا ڈیٹا صحیح قسم کا ہے۔ مثلاً اگر آپ `JSONResponse` واپس کر رہے ہیں تو یہ JSON کے موافق ہو۔ |
||||
|
|
||||
|
اور یہ بھی کہ آپ ایسا کوئی ڈیٹا نہیں بھیج رہے جو `response_model` سے فلٹر ہونا چاہیے تھا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### مزید معلومات { #more-info } |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
آپ `from starlette.responses import Response` یا `from starlette.responses import JSONResponse` بھی استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
**FastAPI** وہی `starlette.responses` فراہم کرتا ہے جو `fastapi.responses` کے طور پر، بس آپ یعنی developer کی سہولت کے لیے۔ لیکن زیادہ تر دستیاب responses براہ راست Starlette سے آتے ہیں۔ |
||||
|
|
||||
|
اور چونکہ `Response` اکثر headers اور cookies مقرر کرنے کے لیے استعمال ہوتا ہے، **FastAPI** اسے `fastapi.Response` پر بھی فراہم کرتا ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
تمام دستیاب parameters اور اختیارات دیکھنے کے لیے، [Starlette کی دستاویزات](https://www.starlette.dev/responses/#set-cookie) دیکھیں۔ |
||||
@ -0,0 +1,83 @@ |
|||||
|
# براہ راست Response واپس کریں { #return-a-response-directly } |
||||
|
|
||||
|
جب آپ **FastAPI** *path operation* بناتے ہیں تو آپ عام طور پر اس سے کوئی بھی ڈیٹا واپس کر سکتے ہیں: ایک `dict`، ایک `list`، ایک Pydantic model، database model وغیرہ۔ |
||||
|
|
||||
|
اگر آپ [Response Model](../tutorial/response-model.md) کا اعلان کرتے ہیں تو FastAPI اسے Pydantic استعمال کر کے ڈیٹا کو JSON میں serialize کرنے کے لیے استعمال کرے گا۔ |
||||
|
|
||||
|
اگر آپ response model کا اعلان نہیں کرتے، تو FastAPI [JSON Compatible Encoder](../tutorial/encoder.md) میں بیان کردہ `jsonable_encoder` استعمال کرے گا اور اسے `JSONResponse` میں ڈالے گا۔ |
||||
|
|
||||
|
آپ براہ راست `JSONResponse` بنا کر بھی واپس کر سکتے ہیں۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
`JSONResponse` براہ راست واپس کرنے کی بجائے [Response Model](../tutorial/response-model.md) استعمال کرنے سے آپ کو عام طور پر بہت بہتر کارکردگی ملے گی، کیونکہ اس طرح یہ Pydantic کا استعمال کرتے ہوئے Rust میں ڈیٹا کو serialize کرتا ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## `Response` واپس کریں { #return-a-response } |
||||
|
|
||||
|
آپ `Response` یا اس کی کوئی بھی sub-class واپس کر سکتے ہیں۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
`JSONResponse` خود `Response` کی ایک sub-class ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
اور جب آپ `Response` واپس کرتے ہیں، **FastAPI** اسے براہ راست منتقل کرے گا۔ |
||||
|
|
||||
|
یہ Pydantic models کے ساتھ کوئی ڈیٹا تبدیلی نہیں کرے گا، مواد کو کسی قسم میں تبدیل نہیں کرے گا وغیرہ۔ |
||||
|
|
||||
|
یہ آپ کو بہت زیادہ **لچک** دیتا ہے۔ آپ کسی بھی ڈیٹا قسم کو واپس کر سکتے ہیں، کسی بھی ڈیٹا اعلان یا توثیق کو تبدیل کر سکتے ہیں وغیرہ۔ |
||||
|
|
||||
|
یہ آپ کو بہت زیادہ **ذمہ داری** بھی دیتا ہے۔ آپ کو یقینی بنانا ہوگا کہ آپ جو ڈیٹا واپس کر رہے ہیں وہ درست ہے، صحیح فارمیٹ میں ہے، serialize ہو سکتا ہے وغیرہ۔ |
||||
|
|
||||
|
## `Response` میں `jsonable_encoder` استعمال کرنا { #using-the-jsonable-encoder-in-a-response } |
||||
|
|
||||
|
چونکہ **FastAPI** آپ کے واپس کردہ `Response` میں کوئی تبدیلی نہیں کرتا، آپ کو یقینی بنانا ہوگا کہ اس کا مواد اس کے لیے تیار ہے۔ |
||||
|
|
||||
|
مثال کے طور پر، آپ Pydantic model کو `JSONResponse` میں پہلے اسے `dict` میں تبدیل کیے بغیر نہیں ڈال سکتے، جس میں تمام ڈیٹا اقسام (جیسے `datetime`، `UUID` وغیرہ) JSON کے موافق اقسام میں تبدیل ہوں۔ |
||||
|
|
||||
|
ان صورتوں میں، آپ `jsonable_encoder` استعمال کر سکتے ہیں اپنے ڈیٹا کو response میں دینے سے پہلے تبدیل کرنے کے لیے: |
||||
|
|
||||
|
{* ../../docs_src/response_directly/tutorial001_py310.py hl[5:6,20:21] *} |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
آپ `from starlette.responses import JSONResponse` بھی استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
**FastAPI** وہی `starlette.responses` فراہم کرتا ہے جو `fastapi.responses` کے طور پر، بس آپ یعنی developer کی سہولت کے لیے۔ لیکن زیادہ تر دستیاب responses براہ راست Starlette سے آتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## حسب ضرورت `Response` واپس کرنا { #returning-a-custom-response } |
||||
|
|
||||
|
اوپر کی مثال تمام ضروری حصے دکھاتی ہے، لیکن ابھی بہت مفید نہیں ہے، کیونکہ آپ صرف `item` براہ راست واپس کر سکتے تھے، اور **FastAPI** اسے آپ کے لیے `JSONResponse` میں ڈال دیتا، اسے `dict` میں تبدیل کر دیتا وغیرہ۔ یہ سب پہلے سے طے شدہ طور پر ہوتا ہے۔ |
||||
|
|
||||
|
اب، آئیں دیکھتے ہیں کہ آپ اسے حسب ضرورت response واپس کرنے کے لیے کیسے استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
فرض کریں کہ آپ [XML](https://en.wikipedia.org/wiki/XML) response واپس کرنا چاہتے ہیں۔ |
||||
|
|
||||
|
آپ اپنا XML مواد ایک string میں رکھ سکتے ہیں، اسے `Response` میں ڈال سکتے ہیں، اور واپس کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *} |
||||
|
|
||||
|
## Response Model کیسے کام کرتا ہے { #how-a-response-model-works } |
||||
|
|
||||
|
جب آپ path operation میں [Response Model - Return Type](../tutorial/response-model.md) کا اعلان کرتے ہیں، **FastAPI** اسے Pydantic استعمال کر کے ڈیٹا کو JSON میں serialize کرنے کے لیے استعمال کرے گا۔ |
||||
|
|
||||
|
{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *} |
||||
|
|
||||
|
چونکہ یہ Rust کی طرف ہوگا، کارکردگی عام Python اور `JSONResponse` class سے بہت بہتر ہوگی۔ |
||||
|
|
||||
|
`response_model` یا return type استعمال کرتے وقت، FastAPI ڈیٹا کو تبدیل کرنے کے لیے `jsonable_encoder` (جو سست ہوتا) اور نہ `JSONResponse` class استعمال کرے گا۔ |
||||
|
|
||||
|
اس کی بجائے یہ response model (یا return type) استعمال کر کے Pydantic سے تیار شدہ JSON bytes لیتا ہے اور JSON کے لیے صحیح media type (`application/json`) کے ساتھ براہ راست `Response` واپس کرتا ہے۔ |
||||
|
|
||||
|
## نوٹس { #notes } |
||||
|
|
||||
|
جب آپ براہ راست `Response` واپس کرتے ہیں تو اس کا ڈیٹا خود بخود توثیق، تبدیل (serialize) یا دستاویزی نہیں ہوتا۔ |
||||
|
|
||||
|
لیکن آپ پھر بھی اسے دستاویزی شکل دے سکتے ہیں جیسا کہ [OpenAPI میں اضافی Responses](additional-responses.md) میں بیان کیا گیا ہے۔ |
||||
|
|
||||
|
آنے والے حصوں میں آپ دیکھ سکتے ہیں کہ خودکار ڈیٹا تبدیلی، دستاویزات وغیرہ رکھتے ہوئے ان حسب ضرورت `Response` کو کیسے استعمال/اعلان کیا جائے۔ |
||||
@ -0,0 +1,41 @@ |
|||||
|
# Response Headers { #response-headers } |
||||
|
|
||||
|
## `Response` parameter استعمال کریں { #use-a-response-parameter } |
||||
|
|
||||
|
آپ اپنے *path operation function* میں `Response` قسم کا parameter اعلان کر سکتے ہیں (جیسا کہ آپ cookies کے لیے کر سکتے ہیں)۔ |
||||
|
|
||||
|
اور پھر آپ اس *عارضی* response آبجیکٹ میں headers مقرر کر سکتے ہیں۔ |
||||
|
|
||||
|
{* ../../docs_src/response_headers/tutorial002_py310.py hl[1, 7:8] *} |
||||
|
|
||||
|
اور پھر آپ جیسے عام طور پر کرتے ہیں، کوئی بھی آبجیکٹ واپس کر سکتے ہیں (ایک `dict`، database model وغیرہ)۔ |
||||
|
|
||||
|
اور اگر آپ نے `response_model` کا اعلان کیا ہے، تو اسے پھر بھی آپ کے واپس کردہ آبجیکٹ کو فلٹر اور تبدیل کرنے کے لیے استعمال کیا جائے گا۔ |
||||
|
|
||||
|
**FastAPI** اس *عارضی* response کو headers (نیز cookies اور status code) نکالنے کے لیے استعمال کرے گا، اور انہیں حتمی response میں ڈالے گا جس میں آپ کی واپس کردہ قدر ہوگی، کسی بھی `response_model` سے فلٹر شدہ۔ |
||||
|
|
||||
|
آپ dependencies میں بھی `Response` parameter کا اعلان کر سکتے ہیں، اور ان میں headers (اور cookies) مقرر کر سکتے ہیں۔ |
||||
|
|
||||
|
## براہ راست `Response` واپس کریں { #return-a-response-directly } |
||||
|
|
||||
|
آپ براہ راست `Response` واپس کرتے وقت بھی headers شامل کر سکتے ہیں۔ |
||||
|
|
||||
|
[براہ راست Response واپس کریں](response-directly.md) میں بیان کردہ طریقے سے response بنائیں اور headers کو اضافی parameter کے طور پر دیں: |
||||
|
|
||||
|
{* ../../docs_src/response_headers/tutorial001_py310.py hl[10:12] *} |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
آپ `from starlette.responses import Response` یا `from starlette.responses import JSONResponse` بھی استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
**FastAPI** وہی `starlette.responses` فراہم کرتا ہے جو `fastapi.responses` کے طور پر، بس آپ یعنی developer کی سہولت کے لیے۔ لیکن زیادہ تر دستیاب responses براہ راست Starlette سے آتے ہیں۔ |
||||
|
|
||||
|
اور چونکہ `Response` اکثر headers اور cookies مقرر کرنے کے لیے استعمال ہوتا ہے، **FastAPI** اسے `fastapi.Response` پر بھی فراہم کرتا ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## حسب ضرورت Headers { #custom-headers } |
||||
|
|
||||
|
ذہن میں رکھیں کہ حسب ضرورت ملکیتی headers [`X-` سابقہ استعمال کر کے](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers) شامل کیے جا سکتے ہیں۔ |
||||
|
|
||||
|
لیکن اگر آپ کے پاس حسب ضرورت headers ہیں جو آپ چاہتے ہیں کہ براؤزر میں ایک client انہیں دیکھ سکے، تو آپ کو انہیں اپنی CORS ترتیبات میں شامل کرنا ہوگا ([CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md) میں مزید پڑھیں)، [Starlette کی CORS دستاویزات](https://www.starlette.dev/middleware/#corsmiddleware) میں بیان کردہ `expose_headers` parameter استعمال کرتے ہوئے۔ |
||||
@ -0,0 +1,107 @@ |
|||||
|
# HTTP Basic Auth { #http-basic-auth } |
||||
|
|
||||
|
سب سے سادہ صورتوں کے لیے، آپ HTTP Basic Auth استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
HTTP Basic Auth میں، ایپلیکیشن ایک ایسا header توقع کرتی ہے جس میں username اور password ہو۔ |
||||
|
|
||||
|
اگر اسے یہ نہیں ملتا، تو یہ HTTP 401 "Unauthorized" error واپس کرتی ہے۔ |
||||
|
|
||||
|
اور `WWW-Authenticate` header واپس کرتی ہے جس کی قدر `Basic` ہوتی ہے، اور ایک اختیاری `realm` parameter۔ |
||||
|
|
||||
|
اس سے browser کو username اور password کے لیے پہلے سے موجود prompt دکھانے کا اشارہ ملتا ہے۔ |
||||
|
|
||||
|
پھر جب آپ وہ username اور password ٹائپ کرتے ہیں، تو browser انہیں خودکار طور پر header میں بھیجتا ہے۔ |
||||
|
|
||||
|
## سادہ HTTP Basic Auth { #simple-http-basic-auth } |
||||
|
|
||||
|
* `HTTPBasic` اور `HTTPBasicCredentials` import کریں۔ |
||||
|
* `HTTPBasic` استعمال کر کے ایک "`security` scheme" بنائیں۔ |
||||
|
* اس `security` کو اپنے *path operation* میں dependency کے ساتھ استعمال کریں۔ |
||||
|
* یہ `HTTPBasicCredentials` قسم کا ایک object واپس کرتا ہے: |
||||
|
* اس میں بھیجے گئے `username` اور `password` ہوتے ہیں۔ |
||||
|
|
||||
|
{* ../../docs_src/security/tutorial006_an_py310.py hl[4,8,12] *} |
||||
|
|
||||
|
جب آپ پہلی بار URL کھولنے کی کوشش کریں گے (یا docs میں "Execute" بٹن پر کلک کریں گے) تو browser آپ سے username اور password پوچھے گا: |
||||
|
|
||||
|
<img src="/img/tutorial/security/image12.png"> |
||||
|
|
||||
|
## Username چیک کریں { #check-the-username } |
||||
|
|
||||
|
یہاں ایک زیادہ مکمل مثال ہے۔ |
||||
|
|
||||
|
username اور password درست ہیں یا نہیں یہ چیک کرنے کے لیے dependency استعمال کریں۔ |
||||
|
|
||||
|
اس کے لیے Python کا معیاری module [`secrets`](https://docs.python.org/3/library/secrets.html) استعمال کریں تاکہ username اور password چیک کیے جا سکیں۔ |
||||
|
|
||||
|
`secrets.compare_digest()` کو `bytes` یا ایسی `str` لینی ہوتی ہے جس میں صرف ASCII حروف ہوں (انگریزی والے)، اس کا مطلب ہے کہ یہ `á` جیسے حروف کے ساتھ کام نہیں کرے گا، جیسے `Sebastián` میں۔ |
||||
|
|
||||
|
اسے سنبھالنے کے لیے، ہم پہلے `username` اور `password` کو UTF-8 سے encode کر کے `bytes` میں تبدیل کرتے ہیں۔ |
||||
|
|
||||
|
پھر ہم `secrets.compare_digest()` استعمال کر سکتے ہیں تاکہ یقینی بنایا جا سکے کہ `credentials.username` `"stanleyjobson"` ہے، اور `credentials.password` `"swordfish"` ہے۔ |
||||
|
|
||||
|
{* ../../docs_src/security/tutorial007_an_py310.py hl[1,12:24] *} |
||||
|
|
||||
|
یہ اس کے مشابہ ہوگا: |
||||
|
|
||||
|
```Python |
||||
|
if not (credentials.username == "stanleyjobson") or not (credentials.password == "swordfish"): |
||||
|
# Return some error |
||||
|
... |
||||
|
``` |
||||
|
|
||||
|
لیکن `secrets.compare_digest()` استعمال کرنے سے یہ "timing attacks" نامی حملوں سے محفوظ رہے گا۔ |
||||
|
|
||||
|
### Timing Attacks { #timing-attacks } |
||||
|
|
||||
|
لیکن "timing attack" کیا ہے؟ |
||||
|
|
||||
|
تصور کریں کہ کچھ حملہ آور username اور password کا اندازہ لگانے کی کوشش کر رہے ہیں۔ |
||||
|
|
||||
|
اور وہ username `johndoe` اور password `love123` کے ساتھ ایک request بھیجتے ہیں۔ |
||||
|
|
||||
|
پھر آپ کی ایپلیکیشن میں Python کوڈ کچھ اس طرح ہوگا: |
||||
|
|
||||
|
```Python |
||||
|
if "johndoe" == "stanleyjobson" and "love123" == "swordfish": |
||||
|
... |
||||
|
``` |
||||
|
|
||||
|
لیکن جس لمحے Python `johndoe` کے پہلے `j` کا `stanleyjobson` کے پہلے `s` سے موازنہ کرتا ہے، یہ `False` واپس کر دے گا، کیونکہ اسے پہلے سے معلوم ہو جاتا ہے کہ یہ دونوں strings ایک جیسی نہیں ہیں، یہ سوچتے ہوئے کہ "باقی حروف کا موازنہ کرنے میں مزید وقت ضائع کرنے کی ضرورت نہیں"۔ اور آپ کی ایپلیکیشن کہے گی "غلط username یا password"۔ |
||||
|
|
||||
|
لیکن پھر حملہ آور username `stanleyjobsox` اور password `love123` کے ساتھ کوشش کرتے ہیں۔ |
||||
|
|
||||
|
اور آپ کی ایپلیکیشن کا کوڈ کچھ ایسا کرتا ہے: |
||||
|
|
||||
|
```Python |
||||
|
if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish": |
||||
|
... |
||||
|
``` |
||||
|
|
||||
|
Python کو `stanleyjobsox` اور `stanleyjobson` دونوں میں پورا `stanleyjobso` موازنہ کرنا ہوگا اس سے پہلے کہ اسے پتا چلے کہ دونوں strings ایک جیسی نہیں ہیں۔ تو "غلط username یا password" جواب دینے میں کچھ اضافی مائیکرو سیکنڈز لگیں گے۔ |
||||
|
|
||||
|
#### جواب دینے کا وقت حملہ آوروں کی مدد کرتا ہے { #the-time-to-answer-helps-the-attackers } |
||||
|
|
||||
|
اس مقام پر، یہ دیکھ کر کہ server نے "غلط username یا password" جواب بھیجنے میں کچھ مائیکرو سیکنڈز زیادہ لگائے، حملہ آوروں کو معلوم ہو جائے گا کہ انہوں نے _کچھ_ درست کیا، ابتدائی حروف میں سے کچھ صحیح تھے۔ |
||||
|
|
||||
|
اور پھر وہ دوبارہ کوشش کر سکتے ہیں یہ جانتے ہوئے کہ یہ شاید `johndoe` سے زیادہ `stanleyjobsox` سے ملتا جلتا ہے۔ |
||||
|
|
||||
|
#### ایک "پیشہ ورانہ" حملہ { #a-professional-attack } |
||||
|
|
||||
|
یقیناً، حملہ آور یہ سب ہاتھ سے نہیں کریں گے، وہ ایک پروگرام لکھیں گے جو ممکنہ طور پر فی سیکنڈ ہزاروں یا لاکھوں ٹیسٹ کرے۔ اور وہ ایک وقت میں صرف ایک اضافی درست حرف حاصل کریں گے۔ |
||||
|
|
||||
|
لیکن ایسا کرنے سے، کچھ منٹوں یا گھنٹوں میں حملہ آوروں نے ہماری ایپلیکیشن کی "مدد" سے، صرف جواب دینے کا وقت استعمال کر کے، صحیح username اور password کا اندازہ لگا لیا ہوگا۔ |
||||
|
|
||||
|
#### `secrets.compare_digest()` سے ٹھیک کریں { #fix-it-with-secrets-compare-digest } |
||||
|
|
||||
|
لیکن ہمارے کوڈ میں ہم دراصل `secrets.compare_digest()` استعمال کر رہے ہیں۔ |
||||
|
|
||||
|
مختصراً، `stanleyjobsox` کا `stanleyjobson` سے موازنہ کرنے میں اتنا ہی وقت لگے گا جتنا `johndoe` کا `stanleyjobson` سے موازنہ میں لگتا ہے۔ اور password کے لیے بھی ایسا ہی ہے۔ |
||||
|
|
||||
|
اس طرح، اپنی ایپلیکیشن کے کوڈ میں `secrets.compare_digest()` استعمال کرنے سے، یہ security حملوں کی اس پوری قسم سے محفوظ رہے گا۔ |
||||
|
|
||||
|
### Error واپس کریں { #return-the-error } |
||||
|
|
||||
|
credentials غلط ہونے کا پتا لگنے کے بعد، status code 401 کے ساتھ ایک `HTTPException` واپس کریں (وہی جو credentials فراہم نہ ہونے پر واپس آتا ہے) اور `WWW-Authenticate` header شامل کریں تاکہ browser دوبارہ login prompt دکھائے: |
||||
|
|
||||
|
{* ../../docs_src/security/tutorial007_an_py310.py hl[26:30] *} |
||||
@ -0,0 +1,19 @@ |
|||||
|
# ایڈوانسڈ Security { #advanced-security } |
||||
|
|
||||
|
## اضافی خصوصیات { #additional-features } |
||||
|
|
||||
|
[ٹیوٹوریل - صارف گائیڈ: Security](../../tutorial/security/index.md) میں شامل خصوصیات کے علاوہ security کو سنبھالنے کے لیے کچھ اضافی خصوصیات موجود ہیں۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
اگلے حصے **ضروری نہیں کہ "ایڈوانسڈ" ہوں**۔ |
||||
|
|
||||
|
اور یہ ممکن ہے کہ آپ کے استعمال کے لیے حل انہی میں سے کسی ایک میں ہو۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## پہلے ٹیوٹوریل پڑھیں { #read-the-tutorial-first } |
||||
|
|
||||
|
اگلے حصے یہ فرض کرتے ہیں کہ آپ پہلے سے مرکزی [ٹیوٹوریل - صارف گائیڈ: Security](../../tutorial/security/index.md) پڑھ چکے ہیں۔ |
||||
|
|
||||
|
یہ سب انہی تصورات پر مبنی ہیں، لیکن کچھ اضافی فعالیت فراہم کرتے ہیں۔ |
||||
@ -0,0 +1,274 @@ |
|||||
|
# OAuth2 scopes { #oauth2-scopes } |
||||
|
|
||||
|
آپ **FastAPI** کے ساتھ براہ راست OAuth2 scopes استعمال کر سکتے ہیں، یہ بغیر کسی رکاوٹ کے کام کرنے کے لیے مربوط ہیں۔ |
||||
|
|
||||
|
یہ آپ کو OAuth2 معیار کے مطابق، آپ کی OpenAPI ایپلیکیشن (اور API docs) میں مربوط، ایک زیادہ باریک بینی سے اجازتوں کا نظام رکھنے کی سہولت دے گا۔ |
||||
|
|
||||
|
OAuth2 with scopes وہ طریقہ کار ہے جو بہت سے بڑے authentication فراہم کنندگان استعمال کرتے ہیں، جیسے Facebook، Google، GitHub، Microsoft، X (Twitter) وغیرہ۔ وہ اسے صارفین اور ایپلیکیشنز کو مخصوص اجازتیں دینے کے لیے استعمال کرتے ہیں۔ |
||||
|
|
||||
|
جب بھی آپ Facebook، Google، GitHub، Microsoft، X (Twitter) کے ساتھ "log in" کرتے ہیں، وہ ایپلیکیشن OAuth2 with scopes استعمال کر رہی ہوتی ہے۔ |
||||
|
|
||||
|
اس حصے میں آپ دیکھیں گے کہ اپنی **FastAPI** ایپلیکیشن میں اسی OAuth2 with scopes کے ساتھ authentication اور authorization کیسے منظم کی جائے۔ |
||||
|
|
||||
|
/// warning | انتباہ |
||||
|
|
||||
|
یہ ایک کم و بیش ایڈوانسڈ حصہ ہے۔ اگر آپ ابھی شروع کر رہے ہیں، تو آپ اسے چھوڑ سکتے ہیں۔ |
||||
|
|
||||
|
آپ کو لازمی طور پر OAuth2 scopes کی ضرورت نہیں، اور آپ authentication اور authorization جیسے چاہیں سنبھال سکتے ہیں۔ |
||||
|
|
||||
|
لیکن OAuth2 with scopes آپ کی API (OpenAPI کے ساتھ) اور آپ کے API docs میں اچھی طرح مربوط ہو سکتا ہے۔ |
||||
|
|
||||
|
بہرحال، آپ ان scopes، یا کسی بھی دوسری security/authorization ضرورت کو، اپنے کوڈ میں جیسے چاہیں نافذ کرتے ہیں۔ |
||||
|
|
||||
|
بہت سی صورتوں میں، OAuth2 with scopes ضرورت سے زیادہ ہو سکتا ہے۔ |
||||
|
|
||||
|
لیکن اگر آپ جانتے ہیں کہ آپ کو اس کی ضرورت ہے، یا آپ متجسس ہیں، تو پڑھتے رہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## OAuth2 scopes اور OpenAPI { #oauth2-scopes-and-openapi } |
||||
|
|
||||
|
OAuth2 specification "scopes" کو خالی جگہوں سے الگ کیے گئے strings کی فہرست کے طور پر بیان کرتی ہے۔ |
||||
|
|
||||
|
ہر ایک string کا مواد کسی بھی شکل میں ہو سکتا ہے، لیکن اس میں خالی جگہیں نہیں ہونی چاہئیں۔ |
||||
|
|
||||
|
یہ scopes "اجازتوں" کی نمائندگی کرتے ہیں۔ |
||||
|
|
||||
|
OpenAPI (مثلاً API docs) میں، آپ "security schemes" بیان کر سکتے ہیں۔ |
||||
|
|
||||
|
جب ان میں سے کوئی security scheme OAuth2 استعمال کرے، تو آپ scopes بھی بیان اور استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
ہر "scope" بس ایک string ہے (بغیر خالی جگہوں کے)۔ |
||||
|
|
||||
|
یہ عام طور پر مخصوص security اجازتیں بیان کرنے کے لیے استعمال ہوتے ہیں، مثال کے طور پر: |
||||
|
|
||||
|
* `users:read` یا `users:write` عام مثالیں ہیں۔ |
||||
|
* `instagram_basic` Facebook / Instagram استعمال کرتا ہے۔ |
||||
|
* `https://www.googleapis.com/auth/drive` Google استعمال کرتا ہے۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
OAuth2 میں "scope" صرف ایک string ہے جو ایک مخصوص مطلوبہ اجازت بیان کرتی ہے۔ |
||||
|
|
||||
|
اس سے کوئی فرق نہیں پڑتا کہ اس میں `:` جیسے دوسرے حروف ہیں یا یہ URL ہے۔ |
||||
|
|
||||
|
یہ تفصیلات عمل درآمد کے لحاظ سے مخصوص ہیں۔ |
||||
|
|
||||
|
OAuth2 کے لیے یہ بس strings ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## مجموعی نظارہ { #global-view } |
||||
|
|
||||
|
پہلے آئیے جلدی سے ان حصوں کو دیکھیں جو مرکزی **ٹیوٹوریل - صارف گائیڈ** کی [OAuth2 with Password (and hashing), Bearer with JWT tokens](../../tutorial/security/oauth2-jwt.md) مثالوں سے تبدیل ہوتے ہیں۔ اب OAuth2 scopes استعمال کرتے ہوئے: |
||||
|
|
||||
|
{* ../../docs_src/security/tutorial005_an_py310.py hl[5,9,13,47,65,106,108:116,122:126,130:136,141,157] *} |
||||
|
|
||||
|
اب آئیے ان تبدیلیوں کا قدم بہ قدم جائزہ لیتے ہیں۔ |
||||
|
|
||||
|
## OAuth2 Security scheme { #oauth2-security-scheme } |
||||
|
|
||||
|
پہلی تبدیلی یہ ہے کہ اب ہم OAuth2 security scheme کو دو دستیاب scopes، `me` اور `items` کے ساتھ بیان کر رہے ہیں۔ |
||||
|
|
||||
|
`scopes` parameter ایک `dict` لیتا ہے جس میں ہر scope بطور key اور وضاحت بطور value ہوتی ہے: |
||||
|
|
||||
|
{* ../../docs_src/security/tutorial005_an_py310.py hl[63:66] *} |
||||
|
|
||||
|
چونکہ ہم اب ان scopes کو بیان کر رہے ہیں، یہ API docs میں جب آپ log-in/authorize کریں گے تو دکھائی دیں گے۔ |
||||
|
|
||||
|
اور آپ منتخب کر سکیں گے کہ آپ کون سے scopes تک رسائی دینا چاہتے ہیں: `me` اور `items`۔ |
||||
|
|
||||
|
یہ وہی طریقہ کار ہے جو Facebook، Google، GitHub وغیرہ کے ساتھ login کرتے وقت اجازتیں دیتے وقت استعمال ہوتا ہے: |
||||
|
|
||||
|
<img src="/img/tutorial/security/image11.png"> |
||||
|
|
||||
|
## Scopes کے ساتھ JWT token { #jwt-token-with-scopes } |
||||
|
|
||||
|
اب token *path operation* میں تبدیلی کریں تاکہ درخواست کیے گئے scopes واپس کیے جائیں۔ |
||||
|
|
||||
|
ہم ابھی بھی وہی `OAuth2PasswordRequestForm` استعمال کر رہے ہیں۔ اس میں `scopes` property شامل ہے جس میں `str` کی `list` ہوتی ہے، request میں موصول ہونے والے ہر scope کے ساتھ۔ |
||||
|
|
||||
|
اور ہم scopes کو JWT token کے حصے کے طور پر واپس کرتے ہیں۔ |
||||
|
|
||||
|
/// danger |
||||
|
|
||||
|
سادگی کے لیے، یہاں ہم موصول ہونے والے scopes کو براہ راست token میں شامل کر رہے ہیں۔ |
||||
|
|
||||
|
لیکن آپ کی ایپلیکیشن میں، security کے لیے، آپ کو یقینی بنانا چاہیے کہ آپ صرف وہ scopes شامل کریں جو صارف واقعی رکھ سکتا ہے، یا جو آپ نے پہلے سے مقرر کیے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
{* ../../docs_src/security/tutorial005_an_py310.py hl[157] *} |
||||
|
|
||||
|
## *path operations* اور dependencies میں scopes بیان کریں { #declare-scopes-in-path-operations-and-dependencies } |
||||
|
|
||||
|
اب ہم بیان کرتے ہیں کہ `/users/me/items/` کے *path operation* کو scope `items` درکار ہے۔ |
||||
|
|
||||
|
اس کے لیے ہم `fastapi` سے `Security` import اور استعمال کرتے ہیں۔ |
||||
|
|
||||
|
آپ `Security` استعمال کر کے dependencies بیان کر سکتے ہیں (بالکل `Depends` کی طرح)، لیکن `Security` ایک اضافی parameter `scopes` بھی لیتا ہے جس میں scopes (strings) کی فہرست ہوتی ہے۔ |
||||
|
|
||||
|
اس صورت میں، ہم dependency function `get_current_active_user` کو `Security` میں دیتے ہیں (اسی طرح جیسے ہم `Depends` کے ساتھ کرتے)۔ |
||||
|
|
||||
|
لیکن ہم scopes کی ایک `list` بھی دیتے ہیں، اس صورت میں صرف ایک scope: `items` (اس میں مزید بھی ہو سکتے ہیں)۔ |
||||
|
|
||||
|
اور dependency function `get_current_active_user` بھی sub-dependencies بیان کر سکتا ہے، نہ صرف `Depends` کے ساتھ بلکہ `Security` کے ساتھ بھی۔ اپنا sub-dependency function (`get_current_user`) بیان کرتے ہوئے، اور مزید scope کی ضروریات۔ |
||||
|
|
||||
|
اس صورت میں، اسے scope `me` درکار ہے (اسے ایک سے زیادہ scopes بھی درکار ہو سکتے ہیں)۔ |
||||
|
|
||||
|
/// note | نوٹ |
||||
|
|
||||
|
آپ کو لازمی طور پر مختلف جگہوں پر مختلف scopes شامل کرنے کی ضرورت نہیں۔ |
||||
|
|
||||
|
ہم یہاں یہ دکھانے کے لیے کر رہے ہیں کہ **FastAPI** مختلف سطحوں پر بیان کیے گئے scopes کو کیسے سنبھالتا ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
{* ../../docs_src/security/tutorial005_an_py310.py hl[5,141,172] *} |
||||
|
|
||||
|
/// info | تکنیکی تفصیلات |
||||
|
|
||||
|
`Security` دراصل `Depends` کی ایک subclass ہے، اور اس میں صرف ایک اضافی parameter ہے جو ہم بعد میں دیکھیں گے۔ |
||||
|
|
||||
|
لیکن `Depends` کی بجائے `Security` استعمال کرنے سے، **FastAPI** جان لے گا کہ وہ security scopes بیان کر سکتا ہے، انہیں اندرونی طور پر استعمال کر سکتا ہے، اور API کو OpenAPI کے ساتھ دستاویز بنا سکتا ہے۔ |
||||
|
|
||||
|
لیکن جب آپ `fastapi` سے `Query`، `Path`، `Depends`، `Security` اور دیگر import کرتے ہیں، تو یہ دراصل ایسے functions ہیں جو خصوصی classes واپس کرتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## `SecurityScopes` استعمال کریں { #use-securityscopes } |
||||
|
|
||||
|
اب dependency `get_current_user` کو اپ ڈیٹ کریں۔ |
||||
|
|
||||
|
یہ وہی ہے جسے اوپر کی dependencies استعمال کرتی ہیں۔ |
||||
|
|
||||
|
یہاں ہم وہی OAuth2 scheme استعمال کر رہے ہیں جو ہم نے پہلے بنایا تھا، اسے dependency کے طور پر بیان کرتے ہوئے: `oauth2_scheme`۔ |
||||
|
|
||||
|
چونکہ اس dependency function کو خود کسی scope کی ضرورت نہیں، ہم `Depends` کو `oauth2_scheme` کے ساتھ استعمال کر سکتے ہیں، جب ہمیں security scopes بیان کرنے کی ضرورت نہ ہو تو `Security` استعمال کرنا ضروری نہیں۔ |
||||
|
|
||||
|
ہم `fastapi.security` سے import کیا ہوا `SecurityScopes` قسم کا ایک خصوصی parameter بھی بیان کرتے ہیں۔ |
||||
|
|
||||
|
یہ `SecurityScopes` class `Request` سے ملتی جلتی ہے (`Request` براہ راست request object حاصل کرنے کے لیے استعمال ہوتا تھا)۔ |
||||
|
|
||||
|
{* ../../docs_src/security/tutorial005_an_py310.py hl[9,106] *} |
||||
|
|
||||
|
## `scopes` استعمال کریں { #use-the-scopes } |
||||
|
|
||||
|
`security_scopes` parameter کی قسم `SecurityScopes` ہوگی۔ |
||||
|
|
||||
|
اس میں `scopes` property ہوگی جس میں خود اور تمام dependencies جو اسے sub-dependency کے طور پر استعمال کرتی ہیں، کے درکار تمام scopes کی فہرست ہوگی۔ یعنی تمام "dependants"... یہ الجھا دینے والا لگ سکتا ہے، نیچے اسے دوبارہ سمجھایا گیا ہے۔ |
||||
|
|
||||
|
`security_scopes` object (`SecurityScopes` class کا) ایک `scope_str` attribute بھی فراہم کرتا ہے جس میں ان scopes پر مشتمل ایک واحد string ہوتی ہے، خالی جگہوں سے الگ (ہم اسے استعمال کریں گے)۔ |
||||
|
|
||||
|
ہم ایک `HTTPException` بناتے ہیں جسے ہم بعد میں کئی مقامات پر دوبارہ استعمال (`raise`) کر سکتے ہیں۔ |
||||
|
|
||||
|
اس exception میں، ہم درکار scopes (اگر کوئی ہوں) خالی جگہوں سے الگ string کے طور پر (`scope_str` استعمال کرتے ہوئے) شامل کرتے ہیں۔ ہم scopes پر مشتمل وہ string `WWW-Authenticate` header میں ڈالتے ہیں (یہ specification کا حصہ ہے)۔ |
||||
|
|
||||
|
{* ../../docs_src/security/tutorial005_an_py310.py hl[106,108:116] *} |
||||
|
|
||||
|
## `username` اور ڈیٹا کی شکل کی تصدیق کریں { #verify-the-username-and-data-shape } |
||||
|
|
||||
|
ہم تصدیق کرتے ہیں کہ ہمیں `username` ملا ہے، اور scopes نکالتے ہیں۔ |
||||
|
|
||||
|
اور پھر ہم اس ڈیٹا کی Pydantic model سے تصدیق کرتے ہیں (`ValidationError` exception پکڑتے ہوئے)، اور اگر JWT token پڑھنے یا Pydantic سے ڈیٹا کی تصدیق کرنے میں کوئی error آئے، تو ہم وہ `HTTPException` raise کرتے ہیں جو ہم نے پہلے بنایا تھا۔ |
||||
|
|
||||
|
اس کے لیے، ہم Pydantic model `TokenData` کو ایک نئی property `scopes` کے ساتھ اپ ڈیٹ کرتے ہیں۔ |
||||
|
|
||||
|
Pydantic سے ڈیٹا کی تصدیق کر کے ہم یقینی بنا سکتے ہیں کہ ہمارے پاس، مثال کے طور پر، scopes کے ساتھ بالکل `str` کی `list` ہے اور `username` کے ساتھ ایک `str`۔ |
||||
|
|
||||
|
مثال کے طور پر، `dict` یا کچھ اور کی بجائے، کیونکہ یہ بعد میں کسی مقام پر ایپلیکیشن کو توڑ سکتا ہے، جو اسے security کا خطرہ بنا دے گا۔ |
||||
|
|
||||
|
ہم یہ بھی تصدیق کرتے ہیں کہ اس username کا صارف موجود ہے، اور اگر نہیں، تو وہی exception raise کرتے ہیں جو ہم نے پہلے بنایا تھا۔ |
||||
|
|
||||
|
{* ../../docs_src/security/tutorial005_an_py310.py hl[47,117:129] *} |
||||
|
|
||||
|
## `scopes` کی تصدیق کریں { #verify-the-scopes } |
||||
|
|
||||
|
اب ہم تصدیق کرتے ہیں کہ اس dependency اور تمام dependants (بشمول *path operations*) کے لیے درکار تمام scopes، موصول ہونے والے token میں فراہم کیے گئے scopes میں شامل ہیں، بصورت دیگر `HTTPException` raise کرتے ہیں۔ |
||||
|
|
||||
|
اس کے لیے ہم `security_scopes.scopes` استعمال کرتے ہیں، جس میں ان تمام scopes کی `list` `str` کے طور پر ہوتی ہے۔ |
||||
|
|
||||
|
{* ../../docs_src/security/tutorial005_an_py310.py hl[130:136] *} |
||||
|
|
||||
|
## Dependency tree اور scopes { #dependency-tree-and-scopes } |
||||
|
|
||||
|
آئیے اس dependency tree اور scopes کا دوبارہ جائزہ لیتے ہیں۔ |
||||
|
|
||||
|
چونکہ `get_current_active_user` dependency کی `get_current_user` پر sub-dependency ہے، اس لیے `get_current_active_user` میں بیان کیا گیا scope `"me"` `get_current_user` کو دیے گئے `security_scopes.scopes` میں درکار scopes کی فہرست میں شامل ہوگا۔ |
||||
|
|
||||
|
*path operation* خود بھی ایک scope بیان کرتا ہے، `"items"`، تو یہ بھی `get_current_user` کو دیے گئے `security_scopes.scopes` کی فہرست میں ہوگا۔ |
||||
|
|
||||
|
یہاں dependencies اور scopes کا درجہ بندی کا نظارہ ہے: |
||||
|
|
||||
|
* *path operation* `read_own_items` میں ہے: |
||||
|
* درکار scopes `["items"]` dependency کے ساتھ: |
||||
|
* `get_current_active_user`: |
||||
|
* dependency function `get_current_active_user` میں ہے: |
||||
|
* درکار scopes `["me"]` dependency کے ساتھ: |
||||
|
* `get_current_user`: |
||||
|
* dependency function `get_current_user` میں ہے: |
||||
|
* خود کوئی scopes درکار نہیں۔ |
||||
|
* `oauth2_scheme` استعمال کرنے والی dependency۔ |
||||
|
* `SecurityScopes` قسم کا `security_scopes` parameter: |
||||
|
* اس `security_scopes` parameter میں `scopes` property ہے جس میں اوپر بیان کیے گئے تمام scopes کی `list` ہے، تو: |
||||
|
* `security_scopes.scopes` *path operation* `read_own_items` کے لیے `["me", "items"]` ہوگا۔ |
||||
|
* `security_scopes.scopes` *path operation* `read_users_me` کے لیے `["me"]` ہوگا، کیونکہ یہ dependency `get_current_active_user` میں بیان کیا گیا ہے۔ |
||||
|
* `security_scopes.scopes` *path operation* `read_system_status` کے لیے `[]` (خالی) ہوگا، کیونکہ اس نے `scopes` کے ساتھ کوئی `Security` بیان نہیں کیا، اور اس کی dependency `get_current_user` بھی کوئی `scopes` بیان نہیں کرتی۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
یہاں اہم اور "جادوئی" بات یہ ہے کہ `get_current_user` ہر *path operation* کے لیے چیک کرنے کے لیے scopes کی مختلف فہرست رکھے گا۔ |
||||
|
|
||||
|
سب کا انحصار ہر *path operation* میں اور اس مخصوص *path operation* کے لیے dependency tree میں ہر dependency میں بیان کیے گئے `scopes` پر ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## `SecurityScopes` کے بارے میں مزید تفصیلات { #more-details-about-securityscopes } |
||||
|
|
||||
|
آپ `SecurityScopes` کسی بھی مقام پر، اور متعدد جگہوں پر استعمال کر سکتے ہیں، یہ ضروری نہیں کہ "root" dependency پر ہو۔ |
||||
|
|
||||
|
اس میں ہمیشہ موجودہ `Security` dependencies اور **اس مخصوص** *path operation* اور **اس مخصوص** dependency tree کے تمام dependants میں بیان کیے گئے security scopes ہوں گے۔ |
||||
|
|
||||
|
چونکہ `SecurityScopes` میں dependants کی طرف سے بیان کیے گئے تمام scopes ہوں گے، آپ اسے ایک مرکزی dependency function میں استعمال کر سکتے ہیں تاکہ تصدیق کی جا سکے کہ token میں درکار scopes موجود ہیں، اور پھر مختلف *path operations* میں مختلف scope کی ضروریات بیان کریں۔ |
||||
|
|
||||
|
ہر *path operation* کے لیے آزادانہ طور پر چیک کیے جائیں گے۔ |
||||
|
|
||||
|
## اسے چیک کریں { #check-it } |
||||
|
|
||||
|
اگر آپ API docs کھولیں، تو آپ authenticate کر سکتے ہیں اور بتا سکتے ہیں کہ آپ کون سے scopes authorize کرنا چاہتے ہیں۔ |
||||
|
|
||||
|
<img src="/img/tutorial/security/image11.png"> |
||||
|
|
||||
|
اگر آپ کوئی scope منتخب نہیں کرتے، تو آپ "authenticated" ہوں گے، لیکن جب آپ `/users/me/` یا `/users/me/items/` تک رسائی حاصل کرنے کی کوشش کریں گے تو آپ کو ایک error ملے گا کہ آپ کے پاس کافی اجازتیں نہیں ہیں۔ آپ پھر بھی `/status/` تک رسائی حاصل کر سکیں گے۔ |
||||
|
|
||||
|
اور اگر آپ scope `me` منتخب کرتے ہیں لیکن scope `items` نہیں، تو آپ `/users/me/` تک رسائی حاصل کر سکیں گے لیکن `/users/me/items/` تک نہیں۔ |
||||
|
|
||||
|
یہ وہی ہوگا جو کسی تیسرے فریق کی ایپلیکیشن کے ساتھ ہوتا جو صارف کی طرف سے فراہم کیے گئے token کے ساتھ ان *path operations* میں سے کسی تک رسائی حاصل کرنے کی کوشش کرتی، اس پر منحصر کہ صارف نے ایپلیکیشن کو کتنی اجازتیں دیں۔ |
||||
|
|
||||
|
## تیسرے فریق کی integrations کے بارے میں { #about-third-party-integrations } |
||||
|
|
||||
|
اس مثال میں ہم OAuth2 "password" flow استعمال کر رہے ہیں۔ |
||||
|
|
||||
|
یہ اس وقت مناسب ہے جب ہم اپنی خود کی ایپلیکیشن میں login کر رہے ہوں، شاید اپنے خود کے frontend کے ساتھ۔ |
||||
|
|
||||
|
کیونکہ ہم `username` اور `password` وصول کرنے پر اعتماد کر سکتے ہیں، کیونکہ ہم اسے کنٹرول کرتے ہیں۔ |
||||
|
|
||||
|
لیکن اگر آپ ایسی OAuth2 ایپلیکیشن بنا رہے ہیں جس سے دوسرے جڑیں گے (یعنی اگر آپ Facebook، Google، GitHub وغیرہ کے مساوی authentication فراہم کنندہ بنا رہے ہیں) تو آپ کو دوسرے flows میں سے کوئی استعمال کرنا چاہیے۔ |
||||
|
|
||||
|
سب سے عام implicit flow ہے۔ |
||||
|
|
||||
|
سب سے محفوظ code flow ہے، لیکن اسے عمل میں لانا زیادہ پیچیدہ ہے کیونکہ اس میں مزید مراحل درکار ہیں۔ چونکہ یہ زیادہ پیچیدہ ہے، بہت سے فراہم کنندگان implicit flow تجویز کرتے ہیں۔ |
||||
|
|
||||
|
/// note | نوٹ |
||||
|
|
||||
|
یہ عام ہے کہ ہر authentication فراہم کنندہ اپنے flows کو مختلف ناموں سے پکارتا ہے، تاکہ اسے اپنے برانڈ کا حصہ بنا سکے۔ |
||||
|
|
||||
|
لیکن آخر میں، وہ وہی OAuth2 معیار نافذ کر رہے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
**FastAPI** ان تمام OAuth2 authentication flows کے لیے `fastapi.security.oauth2` میں utilities شامل کرتا ہے۔ |
||||
|
|
||||
|
## Decorator `dependencies` میں `Security` { #security-in-decorator-dependencies } |
||||
|
|
||||
|
جس طرح آپ decorator کے `dependencies` parameter میں `Depends` کی `list` بیان کر سکتے ہیں (جیسا کہ [Dependencies in path operation decorators](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md) میں سمجھایا گیا ہے)، اسی طرح آپ وہاں `scopes` کے ساتھ `Security` بھی استعمال کر سکتے ہیں۔ |
||||
@ -0,0 +1,302 @@ |
|||||
|
# Settings اور Environment Variables { #settings-and-environment-variables } |
||||
|
|
||||
|
بہت سے معاملات میں آپ کی ایپلیکیشن کو کچھ بیرونی settings یا configurations کی ضرورت ہو سکتی ہے، مثال کے طور پر خفیہ کلیدیں، database credentials، ای میل سروسز کے credentials وغیرہ۔ |
||||
|
|
||||
|
ان میں سے زیادہ تر settings متغیر ہیں (تبدیل ہو سکتی ہیں)، جیسے database URLs۔ اور بہت سی حساس ہو سکتی ہیں، جیسے خفیہ معلومات۔ |
||||
|
|
||||
|
اسی لیے انہیں environment variables میں فراہم کرنا عام ہے جنہیں ایپلیکیشن پڑھتی ہے۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
Environment variables کو سمجھنے کے لیے آپ [Environment Variables](../environment-variables.md) پڑھ سکتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## اقسام اور validation { #types-and-validation } |
||||
|
|
||||
|
یہ environment variables صرف text strings ہینڈل کر سکتے ہیں، کیونکہ یہ Python سے باہر ہیں اور دوسرے پروگراموں اور باقی سسٹم (اور مختلف آپریٹنگ سسٹمز، جیسے Linux، Windows، macOS) کے ساتھ مطابقت رکھنی ہوتی ہے۔ |
||||
|
|
||||
|
اس کا مطلب ہے کہ Python میں environment variable سے پڑھی گئی ہر قدر `str` ہوگی، اور کسی مختلف قسم میں تبدیلی یا کوئی validation کوڈ میں کرنی ہوگی۔ |
||||
|
|
||||
|
## Pydantic `Settings` { #pydantic-settings } |
||||
|
|
||||
|
خوش قسمتی سے، Pydantic environment variables سے آنے والی ان settings کو ہینڈل کرنے کے لیے ایک بہترین utility فراہم کرتا ہے [Pydantic: Settings management](https://docs.pydantic.dev/latest/concepts/pydantic_settings/) کے ساتھ۔ |
||||
|
|
||||
|
### `pydantic-settings` انسٹال کریں { #install-pydantic-settings } |
||||
|
|
||||
|
سب سے پہلے، یقینی بنائیں کہ آپ اپنا [virtual environment](../virtual-environments.md) بنائیں، اسے فعال کریں، اور پھر `pydantic-settings` پیکیج انسٹال کریں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ pip install pydantic-settings |
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
یہ `all` extras انسٹال کرنے پر بھی شامل ہوتا ہے: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ pip install "fastapi[all]" |
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
### `Settings` آبجیکٹ بنائیں { #create-the-settings-object } |
||||
|
|
||||
|
Pydantic سے `BaseSettings` import کریں اور ایک sub-class بنائیں، بالکل Pydantic model کی طرح۔ |
||||
|
|
||||
|
Pydantic models کی طرح ہی، آپ type annotations اور ممکنہ ڈیفالٹ اقدار کے ساتھ class attributes بیان کرتے ہیں۔ |
||||
|
|
||||
|
آپ وہ تمام validation خصوصیات اور ٹولز استعمال کر سکتے ہیں جو آپ Pydantic models کے لیے استعمال کرتے ہیں، جیسے مختلف data اقسام اور `Field()` کے ساتھ اضافی validations۔ |
||||
|
|
||||
|
{* ../../docs_src/settings/tutorial001_py310.py hl[2,5:8,11] *} |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
اگر آپ کاپی اور پیسٹ کے لیے کچھ فوری چاہتے ہیں تو یہ مثال استعمال نہ کریں، نیچے آخری مثال استعمال کریں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
پھر، جب آپ اس `Settings` class کی instance بنائیں گے (اس صورت میں، `settings` آبجیکٹ میں)، Pydantic environment variables کو case-insensitive طریقے سے پڑھے گا، تو بڑے حروف والا variable `APP_NAME` بھی attribute `app_name` کے لیے پڑھا جائے گا۔ |
||||
|
|
||||
|
اس کے بعد یہ ڈیٹا تبدیل اور validate کرے گا۔ تو، جب آپ وہ `settings` آبجیکٹ استعمال کریں گے، آپ کو بیان کردہ اقسام کا ڈیٹا ملے گا (مثلاً `items_per_user` ایک `int` ہوگا)۔ |
||||
|
|
||||
|
### `settings` استعمال کریں { #use-the-settings } |
||||
|
|
||||
|
پھر آپ نیا `settings` آبجیکٹ اپنی ایپلیکیشن میں استعمال کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/settings/tutorial001_py310.py hl[18:20] *} |
||||
|
|
||||
|
### Server چلائیں { #run-the-server } |
||||
|
|
||||
|
اس کے بعد، آپ configurations کو environment variables کے طور پر پاس کرتے ہوئے server چلائیں گے، مثال کے طور پر آپ `ADMIN_EMAIL` اور `APP_NAME` اس طرح سیٹ کر سکتے ہیں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ ADMIN_EMAIL="[email protected]" APP_NAME="ChimichangApp" fastapi run main.py |
||||
|
|
||||
|
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
ایک کمانڈ کے لیے متعدد env vars سیٹ کرنے کے لیے انہیں space سے الگ کریں، اور سب کو کمانڈ سے پہلے رکھیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
اور پھر `admin_email` setting `"[email protected]"` پر سیٹ ہو جائے گی۔ |
||||
|
|
||||
|
`app_name` `"ChimichangApp"` ہوگا۔ |
||||
|
|
||||
|
اور `items_per_user` اپنی ڈیفالٹ قدر `50` پر رہے گا۔ |
||||
|
|
||||
|
## دوسرے module میں Settings { #settings-in-another-module } |
||||
|
|
||||
|
آپ ان settings کو دوسری module فائل میں رکھ سکتے ہیں جیسا کہ آپ نے [بڑی ایپلیکیشنز - متعدد فائلیں](../tutorial/bigger-applications.md) میں دیکھا۔ |
||||
|
|
||||
|
مثال کے طور پر، آپ کے پاس `config.py` فائل ہو سکتی ہے: |
||||
|
|
||||
|
{* ../../docs_src/settings/app01_py310/config.py *} |
||||
|
|
||||
|
اور پھر اسے `main.py` فائل میں استعمال کریں: |
||||
|
|
||||
|
{* ../../docs_src/settings/app01_py310/main.py hl[3,11:13] *} |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
آپ کو `__init__.py` فائل بھی چاہیے ہوگی جیسا کہ آپ نے [بڑی ایپلیکیشنز - متعدد فائلیں](../tutorial/bigger-applications.md) میں دیکھا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Dependency میں Settings { #settings-in-a-dependency } |
||||
|
|
||||
|
بعض اوقات ہر جگہ `settings` کا global آبجیکٹ رکھنے کی بجائے، dependency سے settings فراہم کرنا مفید ہو سکتا ہے۔ |
||||
|
|
||||
|
یہ خاص طور پر testing کے دوران مفید ہو سکتا ہے، کیونکہ dependency کو اپنی حسب ضرورت settings کے ساتھ override کرنا بہت آسان ہے۔ |
||||
|
|
||||
|
### Config فائل { #the-config-file } |
||||
|
|
||||
|
پچھلی مثال سے آتے ہوئے، آپ کی `config.py` فائل اس طرح ہو سکتی ہے: |
||||
|
|
||||
|
{* ../../docs_src/settings/app02_an_py310/config.py hl[10] *} |
||||
|
|
||||
|
غور کریں کہ اب ہم `settings = Settings()` کی ڈیفالٹ instance نہیں بناتے۔ |
||||
|
|
||||
|
### مرکزی ایپ فائل { #the-main-app-file } |
||||
|
|
||||
|
اب ہم ایک dependency بناتے ہیں جو نئی `config.Settings()` واپس کرے۔ |
||||
|
|
||||
|
{* ../../docs_src/settings/app02_an_py310/main.py hl[6,12:13] *} |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
ہم `@lru_cache` کے بارے میں تھوڑی دیر میں بات کریں گے۔ |
||||
|
|
||||
|
ابھی کے لیے آپ فرض کر سکتے ہیں کہ `get_settings()` ایک عام function ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
اور پھر ہم اسے *path operation function* سے dependency کے طور پر طلب کر سکتے ہیں اور جہاں ضرورت ہو استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
{* ../../docs_src/settings/app02_an_py310/main.py hl[17,19:21] *} |
||||
|
|
||||
|
### Settings اور testing { #settings-and-testing } |
||||
|
|
||||
|
پھر testing کے دوران `get_settings` کے لیے dependency override بنا کر مختلف settings آبجیکٹ فراہم کرنا بہت آسان ہوگا: |
||||
|
|
||||
|
{* ../../docs_src/settings/app02_an_py310/test_main.py hl[9:10,13,21] *} |
||||
|
|
||||
|
dependency override میں ہم نئی `Settings` آبجیکٹ بناتے وقت `admin_email` کے لیے نئی قدر سیٹ کرتے ہیں، اور پھر وہ نیا آبجیکٹ واپس کرتے ہیں۔ |
||||
|
|
||||
|
پھر ہم ٹیسٹ کر سکتے ہیں کہ یہ استعمال ہو رہا ہے۔ |
||||
|
|
||||
|
## `.env` فائل پڑھنا { #reading-a-env-file } |
||||
|
|
||||
|
اگر آپ کے پاس بہت سی settings ہیں جو ممکنہ طور پر بہت بدلتی ہیں، شاید مختلف ماحول میں، تو انہیں ایک فائل میں رکھنا اور پھر اسے ایسے پڑھنا مفید ہو سکتا ہے جیسے وہ environment variables ہوں۔ |
||||
|
|
||||
|
یہ رواج کافی عام ہے اور اس کا نام ہے، یہ environment variables عام طور پر `.env` فائل میں رکھے جاتے ہیں، اور فائل کو "dotenv" کہا جاتا ہے۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
نقطے (`.`) سے شروع ہونے والی فائل Unix جیسے سسٹمز، جیسے Linux اور macOS میں ایک پوشیدہ فائل ہوتی ہے۔ |
||||
|
|
||||
|
لیکن dotenv فائل کا واقعی وہی نام ہونا ضروری نہیں ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
Pydantic ایک بیرونی لائبریری استعمال کرتے ہوئے ان قسم کی فائلوں سے پڑھنے کی سپورٹ رکھتا ہے۔ آپ مزید [Pydantic Settings: Dotenv (.env) support](https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support) میں پڑھ سکتے ہیں۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
اس کے کام کرنے کے لیے، آپ کو `pip install python-dotenv` کرنا ہوگا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### `.env` فائل { #the-env-file } |
||||
|
|
||||
|
آپ کے پاس `.env` فائل ہو سکتی ہے جس میں: |
||||
|
|
||||
|
```bash |
||||
|
ADMIN_EMAIL="[email protected]" |
||||
|
APP_NAME="ChimichangApp" |
||||
|
``` |
||||
|
|
||||
|
### `.env` سے settings پڑھیں { #read-settings-from-env } |
||||
|
|
||||
|
اور پھر اپنی `config.py` اس طرح اپ ڈیٹ کریں: |
||||
|
|
||||
|
{* ../../docs_src/settings/app03_an_py310/config.py hl[9] *} |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
`model_config` attribute صرف Pydantic ترتیب کے لیے استعمال ہوتا ہے۔ آپ مزید [Pydantic: Concepts: Configuration](https://docs.pydantic.dev/latest/concepts/config/) میں پڑھ سکتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
یہاں ہم Pydantic `Settings` class کے اندر config `env_file` بیان کرتے ہیں، اور اس dotenv فائل کے filename پر ویلیو سیٹ کرتے ہیں جو ہم استعمال کرنا چاہتے ہیں۔ |
||||
|
|
||||
|
### `lru_cache` کے ساتھ Settings صرف ایک بار بنائیں { #creating-the-settings-only-once-with-lru-cache } |
||||
|
|
||||
|
ڈسک سے فائل پڑھنا عام طور پر مہنگا (سست) عمل ہے، تو آپ شاید یہ صرف ایک بار کرنا چاہیں گے اور پھر وہی settings آبجیکٹ دوبارہ استعمال کریں، ہر request کے لیے پڑھنے کی بجائے۔ |
||||
|
|
||||
|
لیکن ہر بار جب ہم یہ کریں: |
||||
|
|
||||
|
```Python |
||||
|
Settings() |
||||
|
``` |
||||
|
|
||||
|
نیا `Settings` آبجیکٹ بنے گا، اور بنتے وقت `.env` فائل دوبارہ پڑھے گا۔ |
||||
|
|
||||
|
اگر dependency function صرف اس طرح ہوتا: |
||||
|
|
||||
|
```Python |
||||
|
def get_settings(): |
||||
|
return Settings() |
||||
|
``` |
||||
|
|
||||
|
ہم ہر request کے لیے وہ آبجیکٹ بنائیں گے، اور ہر request کے لیے `.env` فائل پڑھیں گے۔ |
||||
|
|
||||
|
لیکن چونکہ ہم اوپر `@lru_cache` decorator استعمال کر رہے ہیں، `Settings` آبجیکٹ صرف ایک بار بنے گا، پہلی بار جب اسے بلایا جائے۔ |
||||
|
|
||||
|
{* ../../docs_src/settings/app03_an_py310/main.py hl[1,11] *} |
||||
|
|
||||
|
پھر `get_settings()` کی اگلی requests کے لیے dependencies میں ہونے والی کسی بھی بعد کی کال کے لیے، `get_settings()` کا اندرونی کوڈ عمل میں لانے اور نیا `Settings` آبجیکٹ بنانے کی بجائے، یہ وہی آبجیکٹ واپس کرے گا جو پہلی بار واپس کیا گیا تھا، بار بار۔ |
||||
|
|
||||
|
#### `lru_cache` تکنیکی تفصیلات { #lru-cache-technical-details } |
||||
|
|
||||
|
`@lru_cache` اس function کو modify کرتا ہے جسے decorate کرتا ہے تاکہ وہی قدر واپس کرے جو پہلی بار واپس کی گئی تھی، function کا کوڈ ہر بار دوبارہ عمل میں لانے کی بجائے۔ |
||||
|
|
||||
|
تو، اس کے نیچے والا function arguments کے ہر مجموعے کے لیے ایک بار عمل میں آئے گا۔ اور پھر ان مجموعوں سے واپس آنے والی اقدار بار بار استعمال ہوں گی جب بھی function کو بالکل وہی مجموعہ arguments کے ساتھ بلایا جائے۔ |
||||
|
|
||||
|
مثال کے طور پر، اگر آپ کے پاس یہ function ہو: |
||||
|
|
||||
|
```Python |
||||
|
@lru_cache |
||||
|
def say_hi(name: str, salutation: str = "Ms."): |
||||
|
return f"Hello {salutation} {name}" |
||||
|
``` |
||||
|
|
||||
|
آپ کا پروگرام اس طرح عمل کر سکتا ہے: |
||||
|
|
||||
|
```mermaid |
||||
|
sequenceDiagram |
||||
|
|
||||
|
participant code as Code |
||||
|
participant function as say_hi() |
||||
|
participant execute as Execute function |
||||
|
|
||||
|
rect rgba(0, 255, 0, .1) |
||||
|
code ->> function: say_hi(name="Camila") |
||||
|
function ->> execute: execute function code |
||||
|
execute ->> code: return the result |
||||
|
end |
||||
|
|
||||
|
rect rgba(0, 255, 255, .1) |
||||
|
code ->> function: say_hi(name="Camila") |
||||
|
function ->> code: return stored result |
||||
|
end |
||||
|
|
||||
|
rect rgba(0, 255, 0, .1) |
||||
|
code ->> function: say_hi(name="Rick") |
||||
|
function ->> execute: execute function code |
||||
|
execute ->> code: return the result |
||||
|
end |
||||
|
|
||||
|
rect rgba(0, 255, 0, .1) |
||||
|
code ->> function: say_hi(name="Rick", salutation="Mr.") |
||||
|
function ->> execute: execute function code |
||||
|
execute ->> code: return the result |
||||
|
end |
||||
|
|
||||
|
rect rgba(0, 255, 255, .1) |
||||
|
code ->> function: say_hi(name="Rick") |
||||
|
function ->> code: return stored result |
||||
|
end |
||||
|
|
||||
|
rect rgba(0, 255, 255, .1) |
||||
|
code ->> function: say_hi(name="Camila") |
||||
|
function ->> code: return stored result |
||||
|
end |
||||
|
``` |
||||
|
|
||||
|
ہماری dependency `get_settings()` کی صورت میں، function کوئی arguments بھی نہیں لیتا، تو یہ ہمیشہ وہی قدر واپس کرتا ہے۔ |
||||
|
|
||||
|
اس طریقے سے، یہ تقریباً ایسے ہی برتاؤ کرتا ہے جیسے یہ صرف ایک global variable ہو۔ لیکن چونکہ یہ dependency function استعمال کرتا ہے، تو ہم اسے testing کے لیے آسانی سے override کر سکتے ہیں۔ |
||||
|
|
||||
|
`@lru_cache` Python کے standard library کے `functools` کا حصہ ہے، آپ اس کے بارے میں مزید [`@lru_cache` کی Python دستاویزات](https://docs.python.org/3/library/functools.html#functools.lru_cache) میں پڑھ سکتے ہیں۔ |
||||
|
|
||||
|
## خلاصہ { #recap } |
||||
|
|
||||
|
آپ Pydantic Settings استعمال کر کے اپنی ایپلیکیشن کی settings یا configurations کو ہینڈل کر سکتے ہیں، Pydantic models کی تمام طاقت کے ساتھ۔ |
||||
|
|
||||
|
* Dependency استعمال کر کے آپ testing آسان بنا سکتے ہیں۔ |
||||
|
* آپ اس کے ساتھ `.env` فائلیں استعمال کر سکتے ہیں۔ |
||||
|
* `@lru_cache` استعمال کر کے آپ dotenv فائل کو ہر request کے لیے بار بار پڑھنے سے بچ سکتے ہیں، جبکہ testing کے دوران اسے override کرنے کی سہولت بھی رہتی ہے۔ |
||||
@ -0,0 +1,117 @@ |
|||||
|
# ڈیٹا Stream کرنا { #stream-data } |
||||
|
|
||||
|
اگر آپ ایسا ڈیٹا stream کرنا چاہتے ہیں جو JSON کے طور پر ترتیب دیا جا سکے، تو آپ کو [Stream JSON Lines](../tutorial/stream-json-lines.md) استعمال کرنا چاہیے۔ |
||||
|
|
||||
|
لیکن اگر آپ **خالص binary ڈیٹا** یا strings stream کرنا چاہتے ہیں، تو یہ طریقہ ہے۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
FastAPI 0.134.0 میں شامل کیا گیا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## استعمال کی صورتیں { #use-cases } |
||||
|
|
||||
|
آپ اسے استعمال کر سکتے ہیں اگر آپ خالص strings stream کرنا چاہیں، مثلاً براہ راست **AI LLM** سروس کے آؤٹ پٹ سے۔ |
||||
|
|
||||
|
آپ اسے **بڑی binary فائلیں** stream کرنے کے لیے بھی استعمال کر سکتے ہیں، جہاں آپ ڈیٹا کا ہر ٹکڑا پڑھتے ہوئے stream کرتے ہیں، بغیر اسے ایک ساتھ پوری memory میں پڑھے۔ |
||||
|
|
||||
|
آپ اس طریقے سے **ویڈیو** یا **آڈیو** بھی stream کر سکتے ہیں، یہ بھی بنایا جا سکتا ہے جب آپ پروسیس اور بھیج رہے ہوں۔ |
||||
|
|
||||
|
## `yield` کے ساتھ `StreamingResponse` { #a-streamingresponse-with-yield } |
||||
|
|
||||
|
اگر آپ اپنے *path operation function* میں `response_class=StreamingResponse` بیان کریں تو آپ `yield` استعمال کر کے ڈیٹا کا ہر ٹکڑا باری باری بھیج سکتے ہیں۔ |
||||
|
|
||||
|
{* ../../docs_src/stream_data/tutorial001_py310.py ln[1:23] hl[20,23] *} |
||||
|
|
||||
|
FastAPI ڈیٹا کا ہر ٹکڑا `StreamingResponse` کو جوں کا توں دے گا، یہ اسے JSON میں تبدیل کرنے یا ایسی کوئی چیز نہیں کرے گا۔ |
||||
|
|
||||
|
### غیر async *path operation functions* { #non-async-path-operation-functions } |
||||
|
|
||||
|
آپ عام `def` functions (بغیر `async`) بھی استعمال کر سکتے ہیں، اور `yield` اسی طرح استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
{* ../../docs_src/stream_data/tutorial001_py310.py ln[26:29] hl[27] *} |
||||
|
|
||||
|
### بغیر Annotation { #no-annotation } |
||||
|
|
||||
|
Streaming binary ڈیٹا کے لیے آپ کو واقعی return type annotation بیان کرنے کی ضرورت نہیں ہے۔ |
||||
|
|
||||
|
چونکہ FastAPI Pydantic کے ساتھ ڈیٹا کو JSON میں تبدیل کرنے یا کسی طرح serialize کرنے کی کوشش نہیں کرے گا، اس صورت میں type annotation صرف آپ کے editor اور tools کے استعمال کے لیے ہے، FastAPI اسے استعمال نہیں کرے گا۔ |
||||
|
|
||||
|
{* ../../docs_src/stream_data/tutorial001_py310.py ln[32:35] hl[33] *} |
||||
|
|
||||
|
اس کا مطلب یہ بھی ہے کہ `StreamingResponse` کے ساتھ آپ کو ڈیٹا bytes بالکل اسی طرح بنانے اور encode کرنے کی **آزادی** اور **ذمہ داری** ہے جیسے آپ انہیں بھیجنا چاہتے ہیں، type annotations سے آزاد۔ |
||||
|
|
||||
|
### Bytes Stream کریں { #stream-bytes } |
||||
|
|
||||
|
اہم استعمال کی صورتوں میں سے ایک strings کی بجائے `bytes` stream کرنا ہے، آپ یقیناً ایسا کر سکتے ہیں۔ |
||||
|
|
||||
|
{* ../../docs_src/stream_data/tutorial001_py310.py ln[44:47] hl[47] *} |
||||
|
|
||||
|
## حسب ضرورت `PNGStreamingResponse` { #a-custom-pngstreamingresponse } |
||||
|
|
||||
|
اوپر کی مثالوں میں، ڈیٹا bytes stream کیے گئے لیکن response میں `Content-Type` header نہیں تھا، اس لیے client نہیں جانتا تھا کہ وہ کس قسم کا ڈیٹا وصول کر رہا ہے۔ |
||||
|
|
||||
|
آپ `StreamingResponse` کی حسب ضرورت sub-class بنا سکتے ہیں جو `Content-Type` header کو آپ کے stream کیے جانے والے ڈیٹا کی قسم پر سیٹ کرے۔ |
||||
|
|
||||
|
مثال کے طور پر، آپ `PNGStreamingResponse` بنا سکتے ہیں جو `media_type` attribute استعمال کرتے ہوئے `Content-Type` header کو `image/png` پر سیٹ کرے: |
||||
|
|
||||
|
{* ../../docs_src/stream_data/tutorial002_py310.py ln[6,19:20] hl[20] *} |
||||
|
|
||||
|
پھر آپ اس نئی class کو اپنے *path operation function* میں `response_class=PNGStreamingResponse` میں استعمال کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/stream_data/tutorial002_py310.py ln[23:27] hl[23] *} |
||||
|
|
||||
|
### فائل کی نقل { #simulate-a-file } |
||||
|
|
||||
|
اس مثال میں، ہم `io.BytesIO` کے ساتھ فائل کی نقل کر رہے ہیں، جو صرف memory میں رہنے والا file-like آبجیکٹ ہے، لیکن وہی interface استعمال کرنے دیتا ہے۔ |
||||
|
|
||||
|
مثال کے طور پر، ہم اس کا مواد حاصل کرنے کے لیے اس پر iterate کر سکتے ہیں، جیسا کہ ہم فائل کے ساتھ کر سکتے ہیں۔ |
||||
|
|
||||
|
{* ../../docs_src/stream_data/tutorial002_py310.py ln[1:27] hl[3,12:13,25] *} |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
دوسرے دو variables، `image_base64` اور `binary_image`، Base64 میں encoded تصویر ہیں، اور پھر bytes میں تبدیل کی گئی ہیں، تاکہ `io.BytesIO` کو پاس کی جا سکیں۔ |
||||
|
|
||||
|
صرف اس لیے کہ یہ اسی فائل میں رہ سکے اس مثال کے لیے اور آپ اسے کاپی کر کے جوں کا توں چلا سکیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
`with` بلاک استعمال کر کے، ہم یقینی بناتے ہیں کہ generator function (`yield` والا function) مکمل ہونے کے بعد file-like آبجیکٹ بند ہو جائے۔ تو، response بھیجنے کے بعد۔ |
||||
|
|
||||
|
اس مخصوص مثال میں یہ اتنا اہم نہیں ہوگا کیونکہ یہ memory میں جعلی فائل ہے (`io.BytesIO` کے ساتھ)، لیکن اصلی فائل کے ساتھ یہ اہم ہوگا کہ کام مکمل ہونے کے بعد فائل بند ہو۔ |
||||
|
|
||||
|
### فائلیں اور Async { #files-and-async } |
||||
|
|
||||
|
زیادہ تر صورتوں میں، file-like آبجیکٹ بطور ڈیفالٹ async اور await کے ساتھ مطابقت نہیں رکھتے۔ |
||||
|
|
||||
|
مثلاً، ان کے پاس `await file.read()` نہیں ہوتا، یا `async for chunk in file`۔ |
||||
|
|
||||
|
اور بہت سی صورتوں میں، انہیں پڑھنا blocking عمل ہوگا (جو event loop کو بلاک کر سکتا ہے)، کیونکہ وہ ڈسک یا نیٹ ورک سے پڑھے جاتے ہیں۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
اوپر والی مثال دراصل ایک استثناء ہے، کیونکہ `io.BytesIO` آبجیکٹ پہلے سے memory میں ہے، تو اسے پڑھنا کچھ بلاک نہیں کرے گا۔ |
||||
|
|
||||
|
لیکن بہت سی صورتوں میں فائل یا file-like آبجیکٹ پڑھنا بلاک کرے گا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
event loop کو بلاک ہونے سے بچانے کے لیے، آپ *path operation function* کو `async def` کی بجائے عام `def` کے ساتھ بیان کر سکتے ہیں، اس طرح FastAPI اسے threadpool worker پر چلائے گا، مرکزی loop کو بلاک ہونے سے بچاتے ہوئے۔ |
||||
|
|
||||
|
{* ../../docs_src/stream_data/tutorial002_py310.py ln[30:34] hl[31] *} |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
اگر آپ کو async function کے اندر سے blocking کوڈ بلانے کی ضرورت ہو، یا blocking function کے اندر سے async function بلانی ہو، تو آپ [Asyncer](https://asyncer.tiangolo.com) استعمال کر سکتے ہیں، جو FastAPI کی ایک ہم خواہر لائبریری ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### `yield from` { #yield-from } |
||||
|
|
||||
|
جب آپ کسی چیز پر iterate کر رہے ہوں، جیسے file-like آبجیکٹ، اور پھر ہر آئٹم کے لیے `yield` کر رہے ہوں، تو آپ `yield from` بھی استعمال کر سکتے ہیں تاکہ ہر آئٹم کو براہ راست yield کریں اور `for` loop سے بچیں۔ |
||||
|
|
||||
|
یہ FastAPI کے لیے مخصوص نہیں ہے، بس Python ہے، لیکن جاننے کے لیے ایک اچھی تدبیر ہے۔ |
||||
|
|
||||
|
{* ../../docs_src/stream_data/tutorial002_py310.py ln[37:40] hl[40] *} |
||||
@ -0,0 +1,88 @@ |
|||||
|
# سخت Content-Type جانچ { #strict-content-type-checking } |
||||
|
|
||||
|
بطور ڈیفالٹ، **FastAPI** JSON request bodies کے لیے `Content-Type` header کی سخت جانچ کرتا ہے، اس کا مطلب ہے کہ JSON requests میں body کو JSON کے طور پر parse کرنے کے لیے درست `Content-Type` header (مثلاً `application/json`) **لازمی** شامل ہونا چاہیے۔ |
||||
|
|
||||
|
## CSRF خطرہ { #csrf-risk } |
||||
|
|
||||
|
یہ ڈیفالٹ رویہ ایک بہت مخصوص صورت میں **Cross-Site Request Forgery (CSRF)** حملوں کی ایک قسم سے تحفظ فراہم کرتا ہے۔ |
||||
|
|
||||
|
یہ حملے اس حقیقت کا فائدہ اٹھاتے ہیں کہ browsers scripts کو بغیر کسی CORS preflight جانچ کے requests بھیجنے دیتے ہیں جب وہ: |
||||
|
|
||||
|
* `Content-Type` header نہ رکھتی ہوں (مثلاً `fetch()` کو `Blob` body کے ساتھ استعمال کرنا) |
||||
|
* اور کوئی authentication credentials نہ بھیجتی ہوں۔ |
||||
|
|
||||
|
اس قسم کا حملہ بنیادی طور پر اس وقت متعلق ہوتا ہے جب: |
||||
|
|
||||
|
* ایپلیکیشن مقامی طور پر (مثلاً `localhost` پر) یا اندرونی نیٹ ورک میں چل رہی ہو |
||||
|
* اور ایپلیکیشن میں کوئی authentication نہ ہو، یہ توقع رکھتی ہو کہ اسی نیٹ ورک سے کوئی بھی request قابل اعتماد ہے۔ |
||||
|
|
||||
|
## حملے کی مثال { #example-attack } |
||||
|
|
||||
|
فرض کریں آپ مقامی AI agent چلانے کا ایک طریقہ بناتے ہیں۔ |
||||
|
|
||||
|
یہ اس پر API فراہم کرتا ہے: |
||||
|
|
||||
|
``` |
||||
|
http://localhost:8000/v1/agents/multivac |
||||
|
``` |
||||
|
|
||||
|
اس پر frontend بھی ہے: |
||||
|
|
||||
|
``` |
||||
|
http://localhost:8000 |
||||
|
``` |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
غور کریں کہ دونوں کا host ایک ہی ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
پھر frontend استعمال کر کے آپ AI agent سے اپنی طرف سے کام کروا سکتے ہیں۔ |
||||
|
|
||||
|
چونکہ یہ **مقامی طور پر** چل رہا ہے، اور کھلے انٹرنیٹ پر نہیں، آپ فیصلہ کرتے ہیں کہ **کوئی authentication** نہ رکھیں، صرف مقامی نیٹ ورک تک رسائی پر بھروسہ کرتے ہوئے۔ |
||||
|
|
||||
|
پھر آپ کے صارفین میں سے کوئی اسے انسٹال اور مقامی طور پر چلا سکتا ہے۔ |
||||
|
|
||||
|
پھر وہ کوئی نقصان دہ ویب سائٹ کھول سکتا ہے، مثلاً: |
||||
|
|
||||
|
``` |
||||
|
https://evilhackers.example.com |
||||
|
``` |
||||
|
|
||||
|
اور وہ نقصان دہ ویب سائٹ `fetch()` سے `Blob` body کے ساتھ مقامی API کو requests بھیجتی ہے: |
||||
|
|
||||
|
``` |
||||
|
http://localhost:8000/v1/agents/multivac |
||||
|
``` |
||||
|
|
||||
|
حالانکہ نقصان دہ ویب سائٹ اور مقامی ایپ کا host مختلف ہے، browser CORS preflight request شروع نہیں کرے گا کیونکہ: |
||||
|
|
||||
|
* یہ بغیر کسی authentication کے چل رہا ہے، اسے کوئی credentials بھیجنے کی ضرورت نہیں۔ |
||||
|
* Browser سمجھتا ہے کہ یہ JSON نہیں بھیج رہا (غائب `Content-Type` header کی وجہ سے)۔ |
||||
|
|
||||
|
پھر نقصان دہ ویب سائٹ مقامی AI agent سے صارف کے سابق باس کو ناراض پیغامات بھیجوا سکتی ہے... یا اس سے بھی بدتر۔ |
||||
|
|
||||
|
## کھلا انٹرنیٹ { #open-internet } |
||||
|
|
||||
|
اگر آپ کی ایپ کھلے انٹرنیٹ پر ہے تو آپ "نیٹ ورک پر بھروسہ" نہیں کریں گے اور بغیر authentication کے کسی کو بھی مراعات یافتہ requests بھیجنے دیں گے۔ |
||||
|
|
||||
|
حملہ آور آسانی سے آپ کے API کو requests بھیجنے کے لیے script چلا سکتے ہیں، browser کی بات چیت کی ضرورت نہیں، تو آپ شاید پہلے سے کسی بھی مراعات یافتہ endpoint کو محفوظ کر رہے ہیں۔ |
||||
|
|
||||
|
اس صورت میں **یہ حملہ/خطرہ آپ پر لاگو نہیں ہوتا**۔ |
||||
|
|
||||
|
یہ خطرہ اور حملہ بنیادی طور پر اس وقت متعلق ہے جب ایپ **مقامی نیٹ ورک** پر چلتی ہے اور یہی **واحد فرض کردہ تحفظ** ہے۔ |
||||
|
|
||||
|
## Content-Type کے بغیر Requests کی اجازت { #allowing-requests-without-content-type } |
||||
|
|
||||
|
اگر آپ کو ایسے clients سپورٹ کرنے ہیں جو `Content-Type` header نہیں بھیجتے، تو آپ `strict_content_type=False` سیٹ کر کے سخت جانچ غیر فعال کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/strict_content_type/tutorial001_py310.py hl[4] *} |
||||
|
|
||||
|
اس setting کے ساتھ، بغیر `Content-Type` header والی requests کی body JSON کے طور پر parse ہوگی، جو FastAPI کے پرانے ورژنز کا وہی رویہ ہے۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
یہ رویہ اور ترتیب FastAPI 0.132.0 میں شامل کی گئی۔ |
||||
|
|
||||
|
/// |
||||
@ -0,0 +1,67 @@ |
|||||
|
# Sub Applications - Mounts { #sub-applications-mounts } |
||||
|
|
||||
|
اگر آپ کو دو آزاد FastAPI ایپلیکیشنز رکھنی ہوں، جن کے اپنے آزاد OpenAPI اور اپنے docs UIs ہوں، تو آپ ایک مرکزی ایپ رکھ سکتے ہیں اور ایک (یا زیادہ) sub-application(s) "mount" کر سکتے ہیں۔ |
||||
|
|
||||
|
## **FastAPI** ایپلیکیشن mount کرنا { #mounting-a-fastapi-application } |
||||
|
|
||||
|
"Mounting" کا مطلب ہے ایک مکمل طور پر "آزاد" ایپلیکیشن کو کسی مخصوص path پر شامل کرنا، جو پھر اس path کے نیچے سب کچھ ہینڈل کرتی ہے، اس sub-application میں بیان کردہ _path operations_ کے ساتھ۔ |
||||
|
|
||||
|
### اعلیٰ سطح کی ایپلیکیشن { #top-level-application } |
||||
|
|
||||
|
سب سے پہلے، مرکزی، اعلیٰ سطح کی **FastAPI** ایپلیکیشن بنائیں، اور اس کی *path operations*: |
||||
|
|
||||
|
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[3, 6:8] *} |
||||
|
|
||||
|
### Sub-application { #sub-application } |
||||
|
|
||||
|
پھر، اپنی sub-application بنائیں، اور اس کی *path operations*۔ |
||||
|
|
||||
|
یہ sub-application صرف ایک اور معیاری FastAPI ایپلیکیشن ہے، لیکن یہ وہ ہے جو "mount" ہوگی: |
||||
|
|
||||
|
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 14:16] *} |
||||
|
|
||||
|
### Sub-application mount کریں { #mount-the-sub-application } |
||||
|
|
||||
|
اپنی اعلیٰ سطح کی ایپلیکیشن `app` میں، sub-application `subapi` کو mount کریں۔ |
||||
|
|
||||
|
اس صورت میں، یہ path `/subapi` پر mount ہوگی: |
||||
|
|
||||
|
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 19] *} |
||||
|
|
||||
|
### خودکار API docs چیک کریں { #check-the-automatic-api-docs } |
||||
|
|
||||
|
اب، `fastapi` کمانڈ چلائیں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ fastapi dev |
||||
|
|
||||
|
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
اور docs کو [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) پر کھولیں۔ |
||||
|
|
||||
|
آپ مرکزی ایپ کی خودکار API docs دیکھیں گے، جس میں صرف اس کی اپنی _path operations_ شامل ہوں گی: |
||||
|
|
||||
|
<img src="/img/tutorial/sub-applications/image01.png"> |
||||
|
|
||||
|
اور پھر، sub-application کی docs [http://127.0.0.1:8000/subapi/docs](http://127.0.0.1:8000/subapi/docs) پر کھولیں۔ |
||||
|
|
||||
|
آپ sub-application کی خودکار API docs دیکھیں گے، جس میں صرف اس کی اپنی _path operations_ شامل ہوں گی، سب درست sub-path prefix `/subapi` کے نیچے: |
||||
|
|
||||
|
<img src="/img/tutorial/sub-applications/image02.png"> |
||||
|
|
||||
|
اگر آپ دونوں user interfaces میں سے کسی کے ساتھ بات چیت کرنے کی کوشش کریں، تو وہ درست طریقے سے کام کریں گے، کیونکہ browser ہر مخصوص ایپ یا sub-app سے بات کر سکے گا۔ |
||||
|
|
||||
|
### تکنیکی تفصیلات: `root_path` { #technical-details-root-path } |
||||
|
|
||||
|
جب آپ اوپر بیان کردہ طریقے سے sub-application mount کرتے ہیں، FastAPI ASGI specification کے ایک مکینزم جسے `root_path` کہتے ہیں، استعمال کرکے sub-application کے mount path کو منتقل کرنے کا خیال رکھتا ہے۔ |
||||
|
|
||||
|
اس طریقے سے، sub-application کو docs UI کے لیے اس path prefix کو استعمال کرنے کا علم ہوگا۔ |
||||
|
|
||||
|
اور sub-application کی اپنی بھی mount شدہ sub-applications ہو سکتی ہیں اور سب کچھ درست طریقے سے کام کرے گا، کیونکہ FastAPI ان تمام `root_path`s کو خود بخود ہینڈل کرتا ہے۔ |
||||
|
|
||||
|
آپ `root_path` اور اسے واضح طور پر استعمال کرنے کے بارے میں مزید [Proxy کے پیچھے](behind-a-proxy.md) سیکشن میں جانیں گے۔ |
||||
@ -0,0 +1,126 @@ |
|||||
|
# Templates { #templates } |
||||
|
|
||||
|
آپ **FastAPI** کے ساتھ کوئی بھی template engine استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
ایک عام انتخاب Jinja2 ہے، وہی جو Flask اور دیگر ٹولز میں استعمال ہوتا ہے۔ |
||||
|
|
||||
|
اسے آسانی سے ترتیب دینے کے لیے utilities موجود ہیں جو آپ اپنی **FastAPI** ایپلیکیشن میں براہ راست استعمال کر سکتے ہیں (Starlette کی فراہم کردہ)۔ |
||||
|
|
||||
|
## Dependencies انسٹال کریں { #install-dependencies } |
||||
|
|
||||
|
یقینی بنائیں کہ آپ [virtual environment](../virtual-environments.md) بنائیں، اسے فعال کریں، اور `jinja2` انسٹال کریں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ pip install jinja2 |
||||
|
|
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
## `Jinja2Templates` استعمال کرنا { #using-jinja2templates } |
||||
|
|
||||
|
* `Jinja2Templates` import کریں۔ |
||||
|
* ایک `templates` آبجیکٹ بنائیں جو آپ بعد میں دوبارہ استعمال کر سکیں۔ |
||||
|
* *path operation* میں `Request` parameter بیان کریں جو template واپس کرے گا۔ |
||||
|
* اپنے بنائے ہوئے `templates` کو render کرنے اور `TemplateResponse` واپس کرنے کے لیے استعمال کریں، template کا نام، request آبجیکٹ، اور Jinja2 template کے اندر استعمال ہونے والے key-value جوڑوں کے ساتھ ایک "context" dictionary پاس کریں۔ |
||||
|
|
||||
|
{* ../../docs_src/templates/tutorial001_py310.py hl[4,11,15:18] *} |
||||
|
|
||||
|
/// note | نوٹ |
||||
|
|
||||
|
FastAPI 0.108.0 اور Starlette 0.29.0 سے پہلے، `name` پہلا parameter تھا۔ |
||||
|
|
||||
|
نیز، اس سے پہلے، پچھلے ورژنز میں، `request` آبجیکٹ Jinja2 کے لیے context میں key-value جوڑوں کے حصے کے طور پر پاس کیا جاتا تھا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
`response_class=HTMLResponse` بیان کرنے سے docs UI جان سکے گا کہ response HTML ہوگا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
آپ `from starlette.templating import Jinja2Templates` بھی استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
**FastAPI** آپ کی سہولت کے لیے `starlette.templating` کو `fastapi.templating` کے طور پر فراہم کرتا ہے۔ لیکن زیادہ تر دستیاب responses براہ راست Starlette سے آتے ہیں۔ `Request` اور `StaticFiles` کے ساتھ بھی ایسا ہی ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Templates لکھنا { #writing-templates } |
||||
|
|
||||
|
پھر آپ `templates/item.html` پر ایک template لکھ سکتے ہیں، مثال کے طور پر: |
||||
|
|
||||
|
```jinja hl_lines="7" |
||||
|
{!../../docs_src/templates/templates/item.html!} |
||||
|
``` |
||||
|
|
||||
|
### Template Context Values { #template-context-values } |
||||
|
|
||||
|
HTML میں جو یہ رکھتا ہے: |
||||
|
|
||||
|
{% raw %} |
||||
|
|
||||
|
```jinja |
||||
|
Item ID: {{ id }} |
||||
|
``` |
||||
|
|
||||
|
{% endraw %} |
||||
|
|
||||
|
...یہ آپ کی پاس کردہ "context" `dict` سے لیا گیا `id` دکھائے گا: |
||||
|
|
||||
|
```Python |
||||
|
{"id": id} |
||||
|
``` |
||||
|
|
||||
|
مثال کے طور پر، ID `42` کے ساتھ، یہ اس طرح render ہوگا: |
||||
|
|
||||
|
```html |
||||
|
Item ID: 42 |
||||
|
``` |
||||
|
|
||||
|
### Template `url_for` Arguments { #template-url-for-arguments } |
||||
|
|
||||
|
آپ template کے اندر `url_for()` بھی استعمال کر سکتے ہیں، یہ وہی arguments لیتا ہے جو آپ کے *path operation function* میں استعمال ہوتے۔ |
||||
|
|
||||
|
تو، یہ حصہ: |
||||
|
|
||||
|
{% raw %} |
||||
|
|
||||
|
```jinja |
||||
|
<a href="{{ url_for('read_item', id=id) }}"> |
||||
|
``` |
||||
|
|
||||
|
{% endraw %} |
||||
|
|
||||
|
...اسی URL کا لنک بنائے گا جو *path operation function* `read_item(id=id)` کے ذریعے ہینڈل ہوگا۔ |
||||
|
|
||||
|
مثال کے طور پر، ID `42` کے ساتھ، یہ اس طرح render ہوگا: |
||||
|
|
||||
|
```html |
||||
|
<a href="/items/42"> |
||||
|
``` |
||||
|
|
||||
|
## Templates اور static فائلیں { #templates-and-static-files } |
||||
|
|
||||
|
آپ template کے اندر `url_for()` بھی استعمال کر سکتے ہیں، اور اسے مثال کے طور پر، `name="static"` کے ساتھ mount کی گئی `StaticFiles` کے ساتھ استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
```jinja hl_lines="4" |
||||
|
{!../../docs_src/templates/templates/item.html!} |
||||
|
``` |
||||
|
|
||||
|
اس مثال میں، یہ `static/styles.css` پر CSS فائل سے لنک کرے گا: |
||||
|
|
||||
|
```CSS hl_lines="4" |
||||
|
{!../../docs_src/templates/static/styles.css!} |
||||
|
``` |
||||
|
|
||||
|
اور چونکہ آپ `StaticFiles` استعمال کر رہے ہیں، وہ CSS فائل آپ کی **FastAPI** ایپلیکیشن کے ذریعے `/static/styles.css` URL پر خود بخود serve ہوگی۔ |
||||
|
|
||||
|
## مزید تفصیلات { #more-details } |
||||
|
|
||||
|
مزید تفصیلات کے لیے، بشمول templates کی جانچ کا طریقہ، [Starlette کی templates دستاویزات](https://www.starlette.dev/templates/) دیکھیں۔ |
||||
@ -0,0 +1,53 @@ |
|||||
|
# Overrides کے ساتھ Dependencies کی جانچ { #testing-dependencies-with-overrides } |
||||
|
|
||||
|
## جانچ کے دوران dependencies کو override کرنا { #overriding-dependencies-during-testing } |
||||
|
|
||||
|
کچھ ایسے منظرنامے ہیں جہاں آپ جانچ کے دوران کسی dependency کو override کرنا چاہیں گے۔ |
||||
|
|
||||
|
آپ نہیں چاہتے کہ اصل dependency چلے (اور نہ ہی اس کی sub-dependencies)۔ |
||||
|
|
||||
|
اس کی بجائے، آپ ایک مختلف dependency فراہم کرنا چاہتے ہیں جو صرف جانچ کے دوران استعمال ہو (ممکنہ طور پر صرف کچھ مخصوص ٹیسٹوں میں)، اور ایسی قدر فراہم کرے جو اصل dependency کی قدر کی جگہ استعمال ہو سکے۔ |
||||
|
|
||||
|
### استعمال کے مواقع: بیرونی سروس { #use-cases-external-service } |
||||
|
|
||||
|
ایک مثال یہ ہو سکتی ہے کہ آپ کے پاس ایک بیرونی authentication فراہم کنندہ ہے جسے آپ کو call کرنا ہے۔ |
||||
|
|
||||
|
آپ اسے ایک token بھیجتے ہیں اور وہ ایک authenticated صارف واپس کرتا ہے۔ |
||||
|
|
||||
|
یہ فراہم کنندہ شاید آپ سے فی request چارج کرتا ہو، اور اسے call کرنے میں ٹیسٹ کے لیے ایک مقررہ mock صارف رکھنے سے زیادہ وقت لگ سکتا ہے۔ |
||||
|
|
||||
|
آپ شاید بیرونی فراہم کنندہ کو ایک بار ٹیسٹ کرنا چاہتے ہیں، لیکن ہر ٹیسٹ کے لیے اسے call کرنا ضروری نہیں۔ |
||||
|
|
||||
|
اس صورت میں، آپ اس dependency کو override کر سکتے ہیں جو فراہم کنندہ کو call کرتی ہے، اور ایک حسب ضرورت dependency استعمال کر سکتے ہیں جو صرف آپ کے ٹیسٹوں کے لیے ایک mock صارف واپس کرتی ہے۔ |
||||
|
|
||||
|
### `app.dependency_overrides` attribute استعمال کریں { #use-the-app-dependency-overrides-attribute } |
||||
|
|
||||
|
ان صورتوں کے لیے، آپ کی **FastAPI** ایپلیکیشن میں ایک attribute `app.dependency_overrides` ہے، یہ ایک سادہ `dict` ہے۔ |
||||
|
|
||||
|
جانچ کے لیے dependency کو override کرنے کے لیے، آپ key کے طور پر اصل dependency (ایک function) رکھیں، اور value کے طور پر اپنی dependency override (ایک اور function)۔ |
||||
|
|
||||
|
اور پھر **FastAPI** اصل dependency کی بجائے اس override کو call کرے گا۔ |
||||
|
|
||||
|
{* ../../docs_src/dependency_testing/tutorial001_an_py310.py hl[26:27,30] *} |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
آپ اپنی **FastAPI** ایپلیکیشن میں کہیں بھی استعمال ہونے والی dependency کے لیے dependency override سیٹ کر سکتے ہیں۔ |
||||
|
|
||||
|
اصل dependency *path operation function*، *path operation decorator* (جب آپ واپسی قدر استعمال نہیں کرتے)، `.include_router()` call وغیرہ میں استعمال ہو سکتی ہے۔ |
||||
|
|
||||
|
FastAPI پھر بھی اسے override کر سکے گا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
پھر آپ `app.dependency_overrides` کو خالی `dict` بنا کر اپنے overrides کو ری سیٹ (ہٹا) سکتے ہیں: |
||||
|
|
||||
|
```Python |
||||
|
app.dependency_overrides = {} |
||||
|
``` |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
اگر آپ صرف کچھ ٹیسٹوں کے دوران dependency override کرنا چاہتے ہیں، تو آپ ٹیسٹ کے شروع میں (test function کے اندر) override سیٹ کر سکتے ہیں اور آخر میں (test function کے آخر میں) اسے ری سیٹ کر سکتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
@ -0,0 +1,12 @@ |
|||||
|
# Events کی جانچ: lifespan اور startup - shutdown { #testing-events-lifespan-and-startup-shutdown } |
||||
|
|
||||
|
جب آپ کو اپنے ٹیسٹوں میں `lifespan` چلانے کی ضرورت ہو، تو آپ `TestClient` کو `with` statement کے ساتھ استعمال کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/app_testing/tutorial004_py310.py hl[9:15,18,27:28,30:32,41:43] *} |
||||
|
|
||||
|
|
||||
|
آپ مزید تفصیلات ["Running lifespan in tests in the official Starlette documentation site."](https://www.starlette.dev/lifespan/#running-lifespan-in-tests) میں پڑھ سکتے ہیں۔ |
||||
|
|
||||
|
فرسودہ `startup` اور `shutdown` events کے لیے، آپ `TestClient` کو اس طرح استعمال کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/app_testing/tutorial003_py310.py hl[9:12,20:24] *} |
||||
@ -0,0 +1,13 @@ |
|||||
|
# WebSockets کی جانچ { #testing-websockets } |
||||
|
|
||||
|
آپ WebSockets کی جانچ کے لیے وہی `TestClient` استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
اس کے لیے، آپ `TestClient` کو `with` statement میں استعمال کریں، WebSocket سے جڑتے ہوئے: |
||||
|
|
||||
|
{* ../../docs_src/app_testing/tutorial002_py310.py hl[27:31] *} |
||||
|
|
||||
|
/// note | نوٹ |
||||
|
|
||||
|
مزید تفصیلات کے لیے، [testing WebSockets](https://www.starlette.dev/testclient/#testing-websocket-sessions) کے بارے میں Starlette کی دستاویزات دیکھیں۔ |
||||
|
|
||||
|
/// |
||||
@ -0,0 +1,56 @@ |
|||||
|
# Request کا براہ راست استعمال { #using-the-request-directly } |
||||
|
|
||||
|
اب تک، آپ request کے ان حصوں کو ان کی اقسام کے ساتھ بیان کرتے رہے ہیں جن کی آپ کو ضرورت ہے۔ |
||||
|
|
||||
|
ڈیٹا لے رہے ہیں: |
||||
|
|
||||
|
* Path سے بطور parameters۔ |
||||
|
* Headers سے۔ |
||||
|
* Cookies سے۔ |
||||
|
* وغیرہ۔ |
||||
|
|
||||
|
اور ایسا کرنے سے، **FastAPI** اس ڈیٹا کو validate کر رہا ہے، اسے تبدیل کر رہا ہے اور آپ کے API کے لیے خود بخود دستاویزات بنا رہا ہے۔ |
||||
|
|
||||
|
لیکن ایسے حالات ہیں جہاں آپ کو `Request` آبجیکٹ تک براہ راست رسائی کی ضرورت ہو سکتی ہے۔ |
||||
|
|
||||
|
## `Request` آبجیکٹ کی تفصیلات { #details-about-the-request-object } |
||||
|
|
||||
|
چونکہ **FastAPI** دراصل اوپر کئی ٹولز کی تہہ کے ساتھ **Starlette** ہے، آپ Starlette کے [`Request`](https://www.starlette.dev/requests/) آبجیکٹ کو ضرورت پڑنے پر براہ راست استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
اس کا مطلب یہ بھی ہوگا کہ اگر آپ `Request` آبجیکٹ سے براہ راست ڈیٹا حاصل کریں (مثلاً body پڑھیں) تو اسے FastAPI کے ذریعے validate، تبدیل یا دستاویز (OpenAPI کے ساتھ، خودکار API user interface کے لیے) نہیں کیا جائے گا۔ |
||||
|
|
||||
|
حالانکہ عام طور پر بیان کردہ کوئی بھی دوسرا parameter (مثلاً Pydantic model کے ساتھ body) پھر بھی validate، تبدیل، annotate وغیرہ ہوگا۔ |
||||
|
|
||||
|
لیکن مخصوص صورتیں ہیں جہاں `Request` آبجیکٹ حاصل کرنا مفید ہے۔ |
||||
|
|
||||
|
## `Request` آبجیکٹ کا براہ راست استعمال { #use-the-request-object-directly } |
||||
|
|
||||
|
فرض کریں آپ اپنے *path operation function* کے اندر client کا IP address/host حاصل کرنا چاہتے ہیں۔ |
||||
|
|
||||
|
اس کے لیے آپ کو request تک براہ راست رسائی درکار ہے۔ |
||||
|
|
||||
|
{* ../../docs_src/using_request_directly/tutorial001_py310.py hl[1,7:8] *} |
||||
|
|
||||
|
*path operation function* parameter کی قسم `Request` بیان کرنے سے **FastAPI** جان لے گا کہ اس parameter میں `Request` پاس کرنا ہے۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
غور کریں کہ اس صورت میں، ہم request parameter کے ساتھ ساتھ path parameter بھی بیان کر رہے ہیں۔ |
||||
|
|
||||
|
تو، path parameter نکالا جائے گا، validate ہوگا، مخصوص قسم میں تبدیل ہوگا اور OpenAPI کے ساتھ annotate ہوگا۔ |
||||
|
|
||||
|
اسی طرح، آپ عام طریقے سے کوئی بھی دوسرا parameter بیان کر سکتے ہیں، اور اس کے ساتھ `Request` بھی حاصل کر سکتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## `Request` دستاویزات { #request-documentation } |
||||
|
|
||||
|
آپ [`Request` آبجیکٹ کے بارے میں مزید تفصیلات Starlette کی سرکاری دستاویزات سائٹ](https://www.starlette.dev/requests/) پر پڑھ سکتے ہیں۔ |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
آپ `from starlette.requests import Request` بھی استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
**FastAPI** اسے آپ کی سہولت کے لیے براہ راست فراہم کرتا ہے۔ لیکن یہ براہ راست Starlette سے آتا ہے۔ |
||||
|
|
||||
|
/// |
||||
@ -0,0 +1,186 @@ |
|||||
|
# WebSockets { #websockets } |
||||
|
|
||||
|
آپ **FastAPI** کے ساتھ [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
## `websockets` انسٹال کریں { #install-websockets } |
||||
|
|
||||
|
یقینی بنائیں کہ آپ [virtual environment](../virtual-environments.md) بنائیں، اسے فعال کریں، اور `websockets` انسٹال کریں (ایک Python لائبریری جو "WebSocket" protocol کو آسانی سے استعمال کرنے کی سہولت دیتی ہے): |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ pip install websockets |
||||
|
|
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
## WebSockets client { #websockets-client } |
||||
|
|
||||
|
### پروڈکشن میں { #in-production } |
||||
|
|
||||
|
آپ کے پروڈکشن سسٹم میں، شاید آپ کے پاس React، Vue.js یا Angular جیسے جدید framework سے بنایا گیا frontend ہوگا۔ |
||||
|
|
||||
|
اور اپنے backend کے ساتھ WebSockets سے رابطہ کرنے کے لیے آپ شاید اپنے frontend کی utilities استعمال کریں گے۔ |
||||
|
|
||||
|
یا آپ کے پاس کوئی native mobile ایپلیکیشن ہو سکتی ہے جو براہ راست native code میں آپ کے WebSocket backend سے رابطہ کرتی ہو۔ |
||||
|
|
||||
|
یا آپ کے پاس WebSocket endpoint سے رابطہ کرنے کا کوئی اور طریقہ ہو سکتا ہے۔ |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
لیکن اس مثال کے لیے، ہم کچھ JavaScript کے ساتھ ایک بہت سادہ HTML document استعمال کریں گے، سب ایک لمبی string کے اندر۔ |
||||
|
|
||||
|
یہ یقیناً بہترین طریقہ نہیں ہے اور آپ اسے پروڈکشن میں استعمال نہیں کریں گے۔ |
||||
|
|
||||
|
پروڈکشن میں آپ کے پاس اوپر بتائے گئے آپشنز میں سے ایک ہوگا۔ |
||||
|
|
||||
|
لیکن WebSockets کی server-side پر توجہ مرکوز کرنے اور ایک کام کرنے والی مثال رکھنے کا یہ سب سے آسان طریقہ ہے: |
||||
|
|
||||
|
{* ../../docs_src/websockets_/tutorial001_py310.py hl[2,6:38,41:43] *} |
||||
|
|
||||
|
## `websocket` بنائیں { #create-a-websocket } |
||||
|
|
||||
|
اپنی **FastAPI** ایپلیکیشن میں، ایک `websocket` بنائیں: |
||||
|
|
||||
|
{* ../../docs_src/websockets_/tutorial001_py310.py hl[1,46:47] *} |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
آپ `from starlette.websockets import WebSocket` بھی استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
**FastAPI** آپ کی سہولت کے لیے وہی `WebSocket` براہ راست فراہم کرتا ہے۔ لیکن یہ براہ راست Starlette سے آتا ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## پیغامات کا انتظار کریں اور پیغامات بھیجیں { #await-for-messages-and-send-messages } |
||||
|
|
||||
|
اپنے WebSocket route میں آپ پیغامات کا `await` کر سکتے ہیں اور پیغامات بھیج سکتے ہیں۔ |
||||
|
|
||||
|
{* ../../docs_src/websockets_/tutorial001_py310.py hl[48:52] *} |
||||
|
|
||||
|
آپ binary، text، اور JSON ڈیٹا وصول اور بھیج سکتے ہیں۔ |
||||
|
|
||||
|
## آزمائیں { #try-it } |
||||
|
|
||||
|
اپنا کوڈ `main.py` فائل میں رکھیں اور پھر اپنی ایپلیکیشن چلائیں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ fastapi dev |
||||
|
|
||||
|
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
اپنا browser [http://127.0.0.1:8000](http://127.0.0.1:8000) پر کھولیں۔ |
||||
|
|
||||
|
آپ کو ایک سادہ صفحہ نظر آئے گا: |
||||
|
|
||||
|
<img src="/img/tutorial/websockets/image01.png"> |
||||
|
|
||||
|
آپ input باکس میں پیغامات ٹائپ کر کے بھیج سکتے ہیں: |
||||
|
|
||||
|
<img src="/img/tutorial/websockets/image02.png"> |
||||
|
|
||||
|
اور آپ کی WebSockets والی **FastAPI** ایپلیکیشن واپس جواب دے گی: |
||||
|
|
||||
|
<img src="/img/tutorial/websockets/image03.png"> |
||||
|
|
||||
|
آپ بہت سے پیغامات بھیج (اور وصول کر) سکتے ہیں: |
||||
|
|
||||
|
<img src="/img/tutorial/websockets/image04.png"> |
||||
|
|
||||
|
اور یہ سب ایک ہی WebSocket connection استعمال کریں گے۔ |
||||
|
|
||||
|
## `Depends` اور دیگر کا استعمال { #using-depends-and-others } |
||||
|
|
||||
|
WebSocket endpoints میں آپ `fastapi` سے import کر کے استعمال کر سکتے ہیں: |
||||
|
|
||||
|
* `Depends` |
||||
|
* `Security` |
||||
|
* `Cookie` |
||||
|
* `Header` |
||||
|
* `Path` |
||||
|
* `Query` |
||||
|
|
||||
|
یہ دوسرے FastAPI endpoints/*path operations* کی طرح ہی کام کرتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/websockets_/tutorial002_an_py310.py hl[68:69,82] *} |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
چونکہ یہ WebSocket ہے تو `HTTPException` raise کرنا واقعی مناسب نہیں ہے، اس کی بجائے ہم `WebSocketException` raise کرتے ہیں۔ |
||||
|
|
||||
|
آپ [specification میں بیان کردہ درست codes](https://tools.ietf.org/html/rfc6455#section-7.4.1) سے closing code استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### Dependencies کے ساتھ WebSockets آزمائیں { #try-the-websockets-with-dependencies } |
||||
|
|
||||
|
اپنی ایپلیکیشن چلائیں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ fastapi dev |
||||
|
|
||||
|
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
اپنا browser [http://127.0.0.1:8000](http://127.0.0.1:8000) پر کھولیں۔ |
||||
|
|
||||
|
وہاں آپ سیٹ کر سکتے ہیں: |
||||
|
|
||||
|
* "Item ID"، جو path میں استعمال ہوتا ہے۔ |
||||
|
* "Token" جو query parameter کے طور پر استعمال ہوتا ہے۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
غور کریں کہ query `token` کو dependency کے ذریعے ہینڈل کیا جائے گا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
اس کے ساتھ آپ WebSocket سے جڑ سکتے ہیں اور پھر پیغامات بھیج اور وصول کر سکتے ہیں: |
||||
|
|
||||
|
<img src="/img/tutorial/websockets/image05.png"> |
||||
|
|
||||
|
## منقطع ہونے اور متعدد clients کو سنبھالنا { #handling-disconnections-and-multiple-clients } |
||||
|
|
||||
|
جب WebSocket connection بند ہوتا ہے تو `await websocket.receive_text()` ایک `WebSocketDisconnect` exception raise کرتا ہے، جسے آپ اس مثال کی طرح پکڑ کر ہینڈل کر سکتے ہیں۔ |
||||
|
|
||||
|
{* ../../docs_src/websockets_/tutorial003_py310.py hl[79:81] *} |
||||
|
|
||||
|
آزمانے کے لیے: |
||||
|
|
||||
|
* ایپ کو کئی browser tabs میں کھولیں۔ |
||||
|
* ان سے پیغامات لکھیں۔ |
||||
|
* پھر ان میں سے ایک tab بند کریں۔ |
||||
|
|
||||
|
اس سے `WebSocketDisconnect` exception raise ہوگا، اور باقی تمام clients کو اس طرح کا پیغام ملے گا: |
||||
|
|
||||
|
``` |
||||
|
Client #1596980209979 left the chat |
||||
|
``` |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
اوپر والی ایپ ایک کم سے کم اور سادہ مثال ہے جو یہ ظاہر کرتی ہے کہ کئی WebSocket connections پر پیغامات کیسے ہینڈل اور broadcast کیے جائیں۔ |
||||
|
|
||||
|
لیکن یاد رکھیں کہ، چونکہ سب کچھ memory میں ایک واحد فہرست میں ہینڈل ہو رہا ہے، یہ صرف اس وقت تک کام کرے گا جب تک process چل رہا ہے، اور صرف ایک واحد process کے ساتھ کام کرے گا۔ |
||||
|
|
||||
|
اگر آپ کو کچھ ایسا چاہیے جو FastAPI کے ساتھ آسانی سے integrate ہو لیکن زیادہ مضبوط ہو، Redis، PostgreSQL یا دیگر کی سپورٹ رکھتا ہو، تو [encode/broadcaster](https://github.com/encode/broadcaster) دیکھیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## مزید معلومات { #more-info } |
||||
|
|
||||
|
آپشنز کے بارے میں مزید جاننے کے لیے، Starlette کی دستاویزات دیکھیں: |
||||
|
|
||||
|
* [`WebSocket` class](https://www.starlette.dev/websockets/) |
||||
|
* [Class پر مبنی WebSocket ہینڈلنگ](https://www.starlette.dev/endpoints/#websocketendpoint) |
||||
@ -0,0 +1,51 @@ |
|||||
|
# WSGI شامل کرنا - Flask, Django, اور دیگر { #including-wsgi-flask-django-others } |
||||
|
|
||||
|
آپ WSGI ایپلیکیشنز کو mount کر سکتے ہیں جیسا کہ آپ نے [Sub Applications - Mounts](sub-applications.md) اور [Proxy کے پیچھے](behind-a-proxy.md) میں دیکھا۔ |
||||
|
|
||||
|
اس کے لیے، آپ `WSGIMiddleware` استعمال کر سکتے ہیں اور اسے اپنی WSGI ایپلیکیشن، مثلاً Flask، Django وغیرہ کو wrap کرنے کے لیے استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
## `WSGIMiddleware` استعمال کرنا { #using-wsgimiddleware } |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
اس کے لیے `a2wsgi` انسٹال کرنا ضروری ہے، مثال کے طور پر `pip install a2wsgi` سے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
آپ کو `a2wsgi` سے `WSGIMiddleware` import کرنا ہوگا۔ |
||||
|
|
||||
|
پھر WSGI (مثلاً Flask) ایپ کو middleware کے ساتھ wrap کریں۔ |
||||
|
|
||||
|
اور پھر اسے ایک path کے نیچے mount کریں۔ |
||||
|
|
||||
|
{* ../../docs_src/wsgi/tutorial001_py310.py hl[1,3,23] *} |
||||
|
|
||||
|
/// note | نوٹ |
||||
|
|
||||
|
پہلے، `fastapi.middleware.wsgi` سے `WSGIMiddleware` استعمال کرنے کی سفارش کی جاتی تھی، لیکن اب یہ deprecated ہے۔ |
||||
|
|
||||
|
اس کی بجائے `a2wsgi` پیکیج استعمال کرنے کی تجویز دی جاتی ہے۔ استعمال کا طریقہ وہی رہتا ہے۔ |
||||
|
|
||||
|
بس یقینی بنائیں کہ `a2wsgi` پیکیج انسٹال ہے اور `WSGIMiddleware` کو `a2wsgi` سے درست طریقے سے import کریں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## چیک کریں { #check-it } |
||||
|
|
||||
|
اب، `/v1/` path کے نیچے ہر request Flask ایپلیکیشن کے ذریعے ہینڈل ہوگی۔ |
||||
|
|
||||
|
اور باقی **FastAPI** کے ذریعے ہینڈل ہوں گی۔ |
||||
|
|
||||
|
اگر آپ اسے چلائیں اور [http://localhost:8000/v1/](http://localhost:8000/v1/) پر جائیں تو آپ کو Flask کا response نظر آئے گا: |
||||
|
|
||||
|
```txt |
||||
|
Hello, World from Flask! |
||||
|
``` |
||||
|
|
||||
|
اور اگر آپ [http://localhost:8000/v2](http://localhost:8000/v2) پر جائیں تو آپ کو FastAPI کا response نظر آئے گا: |
||||
|
|
||||
|
```JSON |
||||
|
{ |
||||
|
"message": "Hello World" |
||||
|
} |
||||
|
``` |
||||
@ -0,0 +1,485 @@ |
|||||
|
# متبادل، تحریک اور موازنے { #alternatives-inspiration-and-comparisons } |
||||
|
|
||||
|
**FastAPI** کو کس چیز نے تحریک دی، یہ متبادل سے کیسے موازنہ کرتا ہے اور اس نے ان سے کیا سیکھا۔ |
||||
|
|
||||
|
## تعارف { #intro } |
||||
|
|
||||
|
**FastAPI** موجود نہ ہوتا اگر دوسروں کا پچھلا کام نہ ہوتا۔ |
||||
|
|
||||
|
پہلے بہت سے tools بنائے گئے ہیں جنہوں نے اس کی تخلیق کی تحریک دی۔ |
||||
|
|
||||
|
میں کئی سالوں سے نیا framework بنانے سے گریز کرتا رہا۔ پہلے میں نے **FastAPI** کی تمام features کو بہت سے مختلف frameworks، plug-ins، اور tools استعمال کرکے حل کرنے کی کوشش کی۔ |
||||
|
|
||||
|
لیکن کسی وقت، کوئی اور راستہ نہیں تھا سوائے اس کے کہ کچھ ایسا بنایا جائے جو یہ تمام features فراہم کرے، پچھلے tools سے بہترین آئیڈیاز لے کر، اور انہیں بہترین ممکنہ طریقے سے ملا کر، زبان کی ان features کو استعمال کرتے ہوئے جو پہلے دستیاب نہیں تھیں (Python 3.6+ type hints)۔ |
||||
|
|
||||
|
## پچھلے tools { #previous-tools } |
||||
|
|
||||
|
### [Django](https://www.djangoproject.com/) { #django } |
||||
|
|
||||
|
یہ سب سے مقبول Python framework ہے اور وسیع پیمانے پر قابل اعتماد ہے۔ اسے Instagram جیسے systems بنانے کے لیے استعمال کیا جاتا ہے۔ |
||||
|
|
||||
|
یہ relational databases (جیسے MySQL یا PostgreSQL) کے ساتھ نسبتاً مضبوطی سے جڑا ہوا ہے، تو NoSQL database (جیسے Couchbase، MongoDB، Cassandra وغیرہ) کو بنیادی storage engine کے طور پر رکھنا بہت آسان نہیں ہے۔ |
||||
|
|
||||
|
یہ backend میں HTML بنانے کے لیے بنایا گیا تھا، نہ کہ جدید frontend (جیسے React، Vue.js اور Angular) یا دوسرے systems (جیسے <abbr title="Internet of Things">IoT</abbr> devices) کے ذریعے استعمال ہونے والی APIs بنانے کے لیے۔ |
||||
|
|
||||
|
### [Django REST Framework](https://www.django-rest-framework.org/) { #django-rest-framework } |
||||
|
|
||||
|
Django REST framework اس لیے بنایا گیا تاکہ Django کے نیچے استعمال کرتے ہوئے Web APIs بنانے کا ایک لچکدار toolkit فراہم کیا جائے، تاکہ اس کی API صلاحیتوں کو بہتر بنایا جا سکے۔ |
||||
|
|
||||
|
اسے Mozilla، Red Hat اور Eventbrite سمیت بہت سی کمپنیاں استعمال کرتی ہیں۔ |
||||
|
|
||||
|
یہ **خودکار API documentation** کی پہلی مثالوں میں سے ایک تھا، اور یہ خاص طور پر ان پہلے آئیڈیاز میں سے ایک تھا جنہوں نے **FastAPI** کی "تلاش" کی تحریک دی۔ |
||||
|
|
||||
|
/// note | نوٹ |
||||
|
|
||||
|
Django REST Framework Tom Christie نے بنایا تھا۔ Starlette اور Uvicorn کے وہی بانی، جن پر **FastAPI** مبنی ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// check | **FastAPI** کو تحریک دی |
||||
|
|
||||
|
خودکار API documentation web user interface رکھنے کی۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### [Flask](https://flask.palletsprojects.com) { #flask } |
||||
|
|
||||
|
Flask ایک "microframework" ہے، اس میں database integrations یا وہ بہت سی چیزیں شامل نہیں ہیں جو Django میں بطور default آتی ہیں۔ |
||||
|
|
||||
|
اس سادگی اور لچک کی وجہ سے NoSQL databases کو بنیادی data storage system کے طور پر استعمال کرنا ممکن ہوتا ہے۔ |
||||
|
|
||||
|
چونکہ یہ بہت سادہ ہے، سیکھنا نسبتاً بدیہی ہے، حالانکہ documentation کچھ مقامات پر تکنیکی ہو جاتی ہے۔ |
||||
|
|
||||
|
اسے عام طور پر ان applications کے لیے بھی استعمال کیا جاتا ہے جن کو ضروری نہیں کہ database، user management، یا Django میں پہلے سے بنی بہت سی features کی ضرورت ہو۔ حالانکہ ان میں سے بہت سی features plug-ins کے ساتھ شامل کی جا سکتی ہیں۔ |
||||
|
|
||||
|
حصوں کی یہ علیحدگی، اور ایک "microframework" ہونا جسے بالکل ضرورت کے مطابق بڑھایا جا سکے، ایک اہم خصوصیت تھی جسے میں برقرار رکھنا چاہتا تھا۔ |
||||
|
|
||||
|
Flask کی سادگی کو دیکھتے ہوئے، یہ APIs بنانے کے لیے اچھا انتخاب لگا۔ اگلی چیز Flask کے لیے ایک "Django REST Framework" تلاش کرنا تھی۔ |
||||
|
|
||||
|
/// check | **FastAPI** کو تحریک دی |
||||
|
|
||||
|
ایک micro-framework ہونے کی۔ ضرورت کے مطابق tools اور حصوں کو ملانا آسان بنانے کی۔ |
||||
|
|
||||
|
سادہ اور استعمال میں آسان routing system رکھنے کی۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### [Requests](https://requests.readthedocs.io) { #requests } |
||||
|
|
||||
|
**FastAPI** دراصل **Requests** کا متبادل نہیں ہے۔ ان کا دائرہ کار بہت مختلف ہے۔ |
||||
|
|
||||
|
درحقیقت FastAPI application کے *اندر* Requests استعمال کرنا عام ہوگا۔ |
||||
|
|
||||
|
لیکن پھر بھی، FastAPI نے Requests سے کافی تحریک لی۔ |
||||
|
|
||||
|
**Requests** APIs کے ساتھ *تعامل* کرنے (بطور client) کی library ہے، جبکہ **FastAPI** APIs *بنانے* (بطور server) کی library ہے۔ |
||||
|
|
||||
|
وہ کم و بیش مخالف سروں پر ہیں، ایک دوسرے کی تکمیل کرتے ہیں۔ |
||||
|
|
||||
|
Requests کا بہت سادہ اور بدیہی ڈیزائن ہے، یہ استعمال میں بہت آسان ہے، معقول defaults کے ساتھ۔ لیکن ساتھ ہی، یہ بہت طاقتور اور حسب ضرورت بنانے کے قابل ہے۔ |
||||
|
|
||||
|
اسی لیے، جیسا کہ سرکاری ویب سائٹ پر کہا گیا ہے: |
||||
|
|
||||
|
> Requests ہر وقت کے سب سے زیادہ download کیے جانے والے Python packages میں سے ایک ہے |
||||
|
|
||||
|
اسے استعمال کرنے کا طریقہ بہت سادہ ہے۔ مثال کے طور پر، `GET` request کرنے کے لیے، آپ یہ لکھیں گے: |
||||
|
|
||||
|
```Python |
||||
|
response = requests.get("http://example.com/some/url") |
||||
|
``` |
||||
|
|
||||
|
FastAPI کا مساوی API *path operation* اس طرح نظر آ سکتا ہے: |
||||
|
|
||||
|
```Python hl_lines="1" |
||||
|
@app.get("/some/url") |
||||
|
def read_url(): |
||||
|
return {"message": "Hello World"} |
||||
|
``` |
||||
|
|
||||
|
`requests.get(...)` اور `@app.get(...)` میں مماثلت دیکھیں۔ |
||||
|
|
||||
|
/// check | **FastAPI** کو تحریک دی |
||||
|
|
||||
|
* سادہ اور بدیہی API رکھنے کی۔ |
||||
|
* HTTP method names (operations) کو براہ راست، سیدھے اور بدیہی طریقے سے استعمال کرنے کی۔ |
||||
|
* معقول defaults رکھنے کی، لیکن طاقتور customizations کے ساتھ۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### [Swagger](https://swagger.io/) / [OpenAPI](https://github.com/OAI/OpenAPI-Specification/) { #swagger-openapi } |
||||
|
|
||||
|
Django REST Framework سے مجھے جو بنیادی feature چاہیے تھا وہ خودکار API documentation تھا۔ |
||||
|
|
||||
|
پھر مجھے پتا چلا کہ JSON (یا YAML، JSON کی ایک extension) استعمال کرکے APIs کو document کرنے کا ایک standard ہے جسے Swagger کہتے ہیں۔ |
||||
|
|
||||
|
اور Swagger APIs کے لیے ایک web user interface پہلے سے بنایا گیا تھا۔ تو، کسی API کے لیے Swagger documentation بنا سکنے سے اس web user interface کو خودکار طور پر استعمال کرنا ممکن ہو جائے گا۔ |
||||
|
|
||||
|
کسی وقت، Swagger کو Linux Foundation کو دے دیا گیا، اور اس کا نام OpenAPI رکھا گیا۔ |
||||
|
|
||||
|
اسی لیے ورژن 2.0 کے بارے میں بات کرتے وقت عام طور پر "Swagger" کہا جاتا ہے، اور ورژن 3+ کے لیے "OpenAPI"۔ |
||||
|
|
||||
|
/// check | **FastAPI** کو تحریک دی |
||||
|
|
||||
|
API specifications کے لیے ایک کھلا standard اپنانے اور استعمال کرنے کی، حسب ضرورت schema کی بجائے۔ |
||||
|
|
||||
|
اور standards پر مبنی user interface tools کو مربوط کرنے کی: |
||||
|
|
||||
|
* [Swagger UI](https://github.com/swagger-api/swagger-ui) |
||||
|
* [ReDoc](https://github.com/Rebilly/ReDoc) |
||||
|
|
||||
|
یہ دونوں کافی مقبول اور مستحکم ہونے کی وجہ سے منتخب کیے گئے، لیکن تیز تلاش سے آپ OpenAPI کے لیے درجنوں متبادل user interfaces تلاش کر سکتے ہیں (جنہیں آپ **FastAPI** کے ساتھ استعمال کر سکتے ہیں)۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### Flask REST frameworks { #flask-rest-frameworks } |
||||
|
|
||||
|
کئی Flask REST frameworks ہیں، لیکن ان کی تحقیق میں وقت اور محنت لگانے کے بعد، میں نے پایا کہ بہت سے بند یا ترک کر دیے گئے ہیں، کئی کھڑے مسائل کے ساتھ جو انہیں ناموزوں بناتے ہیں۔ |
||||
|
|
||||
|
### [Marshmallow](https://marshmallow.readthedocs.io/en/stable/) { #marshmallow } |
||||
|
|
||||
|
API systems کی ایک بنیادی ضرورت data "<dfn title="also called marshalling, conversion">serialization</dfn>" ہے جو code (Python) سے data لے کر اسے network پر بھیجی جا سکنے والی چیز میں تبدیل کرتی ہے۔ مثلاً، database سے data رکھنے والے object کو JSON object میں تبدیل کرنا۔ `datetime` objects کو strings میں تبدیل کرنا، وغیرہ۔ |
||||
|
|
||||
|
APIs کی ایک اور بڑی ضرورت data validation ہے، یہ یقینی بنانا کہ data درست ہے مخصوص parameters کے مطابق۔ مثلاً، کوئی field `int` ہے نہ کہ کوئی random string۔ یہ آنے والے data کے لیے خاص طور پر مفید ہے۔ |
||||
|
|
||||
|
Data validation system کے بغیر، آپ کو code میں تمام checks خود کرنے ہوں گے۔ |
||||
|
|
||||
|
یہی features ہیں جو Marshmallow فراہم کرنے کے لیے بنایا گیا تھا۔ یہ ایک بہترین library ہے، اور میں نے اسے پہلے بہت استعمال کیا ہے۔ |
||||
|
|
||||
|
لیکن یہ Python type hints سے پہلے بنایا گیا تھا۔ تو ہر <dfn title="the definition of how data should be formed">schema</dfn> define کرنے کے لیے Marshmallow کی فراہم کردہ مخصوص utils اور classes استعمال کرنی ہوتی ہیں۔ |
||||
|
|
||||
|
/// check | **FastAPI** کو تحریک دی |
||||
|
|
||||
|
Data types اور validation فراہم کرنے والے "schemas" define کرنے کے لیے code استعمال کرنے کی، خودکار طور پر۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### [Webargs](https://webargs.readthedocs.io/en/latest/) { #webargs } |
||||
|
|
||||
|
APIs کی ایک اور بڑی ضرورت آنے والی requests سے data <dfn title="reading and converting to Python data">parsing</dfn> ہے۔ |
||||
|
|
||||
|
Webargs ایک tool ہے جو کئی frameworks بشمول Flask کے اوپر یہ سہولت فراہم کرنے کے لیے بنایا گیا تھا۔ |
||||
|
|
||||
|
یہ data validation کے لیے Marshmallow استعمال کرتا ہے۔ اور اسے انہی developers نے بنایا تھا۔ |
||||
|
|
||||
|
یہ ایک بہترین tool ہے اور میں نے اسے بھی **FastAPI** سے پہلے بہت استعمال کیا ہے۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
Webargs وہی Marshmallow developers نے بنایا تھا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// check | **FastAPI** کو تحریک دی |
||||
|
|
||||
|
آنے والے request data کی خودکار validation رکھنے کی۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### [APISpec](https://apispec.readthedocs.io/en/stable/) { #apispec } |
||||
|
|
||||
|
Marshmallow اور Webargs plug-ins کے طور پر validation، parsing اور serialization فراہم کرتے ہیں۔ |
||||
|
|
||||
|
لیکن documentation ابھی بھی نہیں تھی۔ پھر APISpec بنایا گیا۔ |
||||
|
|
||||
|
یہ بہت سے frameworks کے لیے plug-in ہے (اور Starlette کے لیے بھی ایک plug-in ہے)۔ |
||||
|
|
||||
|
یہ اس طرح کام کرتا ہے کہ آپ route handle کرنے والے ہر function کی docstring میں YAML فارمیٹ استعمال کرکے schema کی definition لکھتے ہیں۔ |
||||
|
|
||||
|
اور یہ OpenAPI schemas بناتا ہے۔ |
||||
|
|
||||
|
Flask، Starlette، Responder وغیرہ میں یہی طریقہ ہے۔ |
||||
|
|
||||
|
لیکن پھر، ہمارے پاس دوبارہ Python string (ایک بڑا YAML) کے اندر ایک micro-syntax کا مسئلہ ہے۔ |
||||
|
|
||||
|
Editor اس میں زیادہ مدد نہیں کر سکتا۔ اور اگر ہم parameters یا Marshmallow schemas تبدیل کریں اور وہ YAML docstring بھی اپڈیٹ کرنا بھول جائیں، تو بنایا گیا schema متروک ہو جائے گا۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
APISpec وہی Marshmallow developers نے بنایا تھا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// check | **FastAPI** کو تحریک دی |
||||
|
|
||||
|
APIs کے لیے کھلے standard، OpenAPI، کی حمایت کرنے کی۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### [Flask-apispec](https://flask-apispec.readthedocs.io/en/latest/) { #flask-apispec } |
||||
|
|
||||
|
یہ ایک Flask plug-in ہے، جو Webargs، Marshmallow اور APISpec کو جوڑتا ہے۔ |
||||
|
|
||||
|
یہ Webargs اور Marshmallow سے معلومات استعمال کرکے APISpec کے ذریعے خودکار OpenAPI schemas بناتا ہے۔ |
||||
|
|
||||
|
یہ ایک بہترین tool ہے، بہت کم قدردانی حاصل۔ اسے وہاں بہت سے Flask plug-ins سے زیادہ مقبول ہونا چاہیے۔ اس کی وجہ شاید اس کی documentation کا بہت مختصر اور تجریدی ہونا ہے۔ |
||||
|
|
||||
|
اس نے Python docstrings کے اندر YAML (ایک اور syntax) لکھنے کا مسئلہ حل کیا۔ |
||||
|
|
||||
|
Flask، Flask-apispec بمع Marshmallow اور Webargs کا یہ مجموعہ **FastAPI** بنانے تک میرا پسندیدہ backend stack تھا۔ |
||||
|
|
||||
|
اسے استعمال کرنے سے کئی Flask full-stack generators بنے۔ یہ وہ بنیادی stacks ہیں جو میں (اور کئی بیرونی ٹیمیں) اب تک استعمال کرتے رہے ہیں: |
||||
|
|
||||
|
* [https://github.com/tiangolo/full-stack](https://github.com/tiangolo/full-stack) |
||||
|
* [https://github.com/tiangolo/full-stack-flask-couchbase](https://github.com/tiangolo/full-stack-flask-couchbase) |
||||
|
* [https://github.com/tiangolo/full-stack-flask-couchdb](https://github.com/tiangolo/full-stack-flask-couchdb) |
||||
|
|
||||
|
اور یہی full-stack generators [**FastAPI** Project Generators](project-generation.md) کی بنیاد تھے۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
Flask-apispec وہی Marshmallow developers نے بنایا تھا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// check | **FastAPI** کو تحریک دی |
||||
|
|
||||
|
اسی code سے جو serialization اور validation define کرتا ہے، خودکار طور پر OpenAPI schema بنانے کی۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### [NestJS](https://nestjs.com/) (اور [Angular](https://angular.io/)) { #nestjs-and-angular } |
||||
|
|
||||
|
یہ Python بھی نہیں ہے، NestJS ایک JavaScript (TypeScript) NodeJS framework ہے جو Angular سے تحریک یافتہ ہے۔ |
||||
|
|
||||
|
یہ کچھ حد تک ایسا ہی حاصل کرتا ہے جو Flask-apispec سے کیا جا سکتا ہے۔ |
||||
|
|
||||
|
اس میں Angular 2 سے تحریک یافتہ ایک مربوط dependency injection system ہے۔ اسے "injectables" کو پہلے سے register کرنا ضروری ہے (جیسے میں جانتا ہوں تمام dependency injection systems)، تو یہ طوالت اور code کی تکرار میں اضافہ کرتا ہے۔ |
||||
|
|
||||
|
چونکہ parameters TypeScript types سے بیان کیے جاتے ہیں (Python type hints کی طرح)، editor support کافی اچھا ہے۔ |
||||
|
|
||||
|
لیکن چونکہ TypeScript data JavaScript میں compile ہونے کے بعد محفوظ نہیں رہتا، یہ validation، serialization اور documentation ایک ساتھ define کرنے کے لیے types پر انحصار نہیں کر سکتا۔ اس اور کچھ design فیصلوں کی وجہ سے، validation، serialization اور خودکار schema generation حاصل کرنے کے لیے بہت سی جگہوں پر decorators شامل کرنے ہوتے ہیں۔ تو یہ کافی طویل ہو جاتا ہے۔ |
||||
|
|
||||
|
یہ nested models کو بہت اچھی طرح سنبھال نہیں سکتا۔ تو اگر request میں JSON body ایک JSON object ہے جس میں اندر کے fields بدلے میں nested JSON objects ہیں، تو اسے ٹھیک سے document اور validate نہیں کیا جا سکتا۔ |
||||
|
|
||||
|
/// check | **FastAPI** کو تحریک دی |
||||
|
|
||||
|
بہترین editor support حاصل کرنے کے لیے Python types استعمال کرنے کی۔ |
||||
|
|
||||
|
طاقتور dependency injection system رکھنے کی۔ Code کی تکرار کم کرنے کا طریقہ ڈھونڈنے کی۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### [Sanic](https://sanic.readthedocs.io/en/latest/) { #sanic } |
||||
|
|
||||
|
یہ `asyncio` پر مبنی انتہائی تیز Python frameworks میں سے پہلے تھا۔ اسے Flask سے بہت ملتا جلتا بنایا گیا تھا۔ |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
اس نے default Python `asyncio` loop کی بجائے [`uvloop`](https://github.com/MagicStack/uvloop) استعمال کیا۔ یہی اسے اتنا تیز بنایا۔ |
||||
|
|
||||
|
اس نے واضح طور پر Uvicorn اور Starlette کو تحریک دی، جو فی الحال کھلے benchmarks میں Sanic سے تیز ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// check | **FastAPI** کو تحریک دی |
||||
|
|
||||
|
زبردست performance حاصل کرنے کا طریقہ ڈھونڈنے کی۔ |
||||
|
|
||||
|
اسی لیے **FastAPI** Starlette پر مبنی ہے، کیونکہ یہ دستیاب تیز ترین framework ہے (third-party benchmarks سے ٹیسٹ شدہ)۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### [Falcon](https://falconframework.org/) { #falcon } |
||||
|
|
||||
|
Falcon ایک اور اعلیٰ performance Python framework ہے، اسے کم سے کم ہونے کے لیے ڈیزائن کیا گیا ہے، اور دوسرے frameworks جیسے Hug کی بنیاد کے طور پر کام کرنے کے لیے۔ |
||||
|
|
||||
|
اسے ایسے functions رکھنے کے لیے ڈیزائن کیا گیا ہے جو دو parameters وصول کرتے ہیں، ایک "request" اور ایک "response"۔ پھر آپ request سے حصے "پڑھتے" ہیں، اور response میں حصے "لکھتے" ہیں۔ اس ڈیزائن کی وجہ سے، function parameters کے طور پر standard Python type hints کے ساتھ request parameters اور bodies declare کرنا ممکن نہیں ہے۔ |
||||
|
|
||||
|
تو data validation، serialization، اور documentation code میں کرنی ہوتی ہے، خودکار طور پر نہیں۔ یا انہیں Falcon کے اوپر framework کے طور پر implement کرنا ہوتا ہے، جیسے Hug۔ یہی فرق ان دوسرے frameworks میں ہوتا ہے جو Falcon کے ڈیزائن سے تحریک یافتہ ہیں، ایک request object اور ایک response object بطور parameters رکھنے کا۔ |
||||
|
|
||||
|
/// check | **FastAPI** کو تحریک دی |
||||
|
|
||||
|
بہترین performance حاصل کرنے کے طریقے ڈھونڈنے کی۔ |
||||
|
|
||||
|
Hug کے ساتھ مل کر (چونکہ Hug، Falcon پر مبنی ہے) **FastAPI** کو functions میں `response` parameter declare کرنے کی تحریک دی۔ |
||||
|
|
||||
|
حالانکہ FastAPI میں یہ اختیاری ہے، اور بنیادی طور پر headers، cookies، اور متبادل status codes سیٹ کرنے کے لیے استعمال ہوتا ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### [Molten](https://moltenframework.com/) { #molten } |
||||
|
|
||||
|
میں نے **FastAPI** بنانے کے ابتدائی مراحل میں Molten دریافت کیا۔ اور اس کے کافی ملتے جلتے آئیڈیاز ہیں: |
||||
|
|
||||
|
* Python type hints پر مبنی۔ |
||||
|
* ان types سے validation اور documentation۔ |
||||
|
* Dependency Injection system۔ |
||||
|
|
||||
|
یہ Pydantic جیسی data validation، serialization اور documentation third-party library استعمال نہیں کرتا، بلکہ اس کی اپنی ہے۔ تو یہ data type definitions آسانی سے دوبارہ استعمال نہیں ہوتیں۔ |
||||
|
|
||||
|
اسے تھوڑی زیادہ verbose configurations کی ضرورت ہے۔ اور چونکہ یہ WSGI (ASGI کی بجائے) پر مبنی ہے، اسے Uvicorn، Starlette اور Sanic جیسے tools کی اعلیٰ performance کا فائدہ اٹھانے کے لیے ڈیزائن نہیں کیا گیا۔ |
||||
|
|
||||
|
Dependency injection system dependencies کو پہلے سے register کرنے اور declare کیے گئے types کی بنیاد پر resolve کرنے کی ضرورت ہے۔ تو ایک مخصوص type فراہم کرنے والے ایک سے زیادہ "component" declare کرنا ممکن نہیں ہے۔ |
||||
|
|
||||
|
Routes ایک ہی جگہ declare کیے جاتے ہیں، دوسری جگہوں پر declare کیے گئے functions کا استعمال کرتے ہوئے (endpoint handle کرنے والے function کے بالکل اوپر رکھے جا سکنے والے decorators استعمال کرنے کی بجائے)۔ یہ Django کے طریقے سے زیادہ قریب ہے بنسبت Flask (اور Starlette) کے۔ یہ code میں ان چیزوں کو الگ کرتا ہے جو نسبتاً مضبوطی سے جڑی ہوتی ہیں۔ |
||||
|
|
||||
|
/// check | **FastAPI** کو تحریک دی |
||||
|
|
||||
|
Model attributes کی "default" value استعمال کرکے data types کے لیے اضافی validations define کرنے کی۔ اس سے editor support بہتر ہوا، اور یہ پہلے Pydantic میں دستیاب نہیں تھا۔ |
||||
|
|
||||
|
اس نے دراصل Pydantic کے حصے اپڈیٹ کرنے کی تحریک دی، تاکہ وہی validation declaration style سہولت فراہم ہو (یہ ساری functionality اب پہلے سے Pydantic میں دستیاب ہے)۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### [Hug](https://github.com/hugapi/hug) { #hug } |
||||
|
|
||||
|
Hug ان پہلے frameworks میں سے ایک تھا جنہوں نے Python type hints استعمال کرکے API parameter types declare کرنا implement کیا۔ یہ ایک زبردست آئیڈیا تھا جس نے دوسرے tools کو بھی ایسا کرنے کی تحریک دی۔ |
||||
|
|
||||
|
اس نے اپنی declarations میں standard Python types کی بجائے custom types استعمال کیے، لیکن یہ پھر بھی آگے کی طرف ایک بڑا قدم تھا۔ |
||||
|
|
||||
|
یہ JSON میں API کی پوری declaration کا ایک custom schema بنانے والے پہلے frameworks میں سے بھی تھا۔ |
||||
|
|
||||
|
یہ OpenAPI اور JSON Schema جیسے standard پر مبنی نہیں تھا۔ تو اسے Swagger UI جیسے دوسرے tools کے ساتھ مربوط کرنا سیدھا نہیں ہوتا۔ لیکن پھر بھی، یہ ایک بہت اختراعی آئیڈیا تھا۔ |
||||
|
|
||||
|
اس میں ایک دلچسپ، غیر معمولی feature ہے: ایک ہی framework استعمال کرکے APIs اور CLIs دونوں بنانا ممکن ہے۔ |
||||
|
|
||||
|
چونکہ یہ synchronous Python web frameworks کے پچھلے standard (WSGI) پر مبنی ہے، یہ Websockets اور دوسری چیزیں سنبھال نہیں سکتا، حالانکہ اس کی performance بھی اعلیٰ ہے۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
Hug Timothy Crosley نے بنایا تھا، [`isort`](https://github.com/timothycrosley/isort) کے وہی بانی، Python فائلوں میں imports کو خودکار ترتیب دینے کا ایک بہترین tool۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// check | **FastAPI** کو تحریک دینے والے آئیڈیاز |
||||
|
|
||||
|
Hug نے APIStar کے حصوں کی تحریک دی، اور وہ tools میں سے ایک تھا جو مجھے APIStar کے ساتھ سب سے زیادہ امید افزا لگا۔ |
||||
|
|
||||
|
Hug نے **FastAPI** کو Python type hints استعمال کرکے parameters declare کرنے، اور API define کرنے والا schema خودکار بنانے کی تحریک دی۔ |
||||
|
|
||||
|
Hug نے **FastAPI** کو functions میں `response` parameter declare کرنے کی تحریک دی تاکہ headers اور cookies سیٹ کیے جا سکیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### [APIStar](https://github.com/encode/apistar) (<= 0.5) { #apistar-0-5 } |
||||
|
|
||||
|
**FastAPI** بنانے کا فیصلہ کرنے سے ٹھیک پہلے مجھے **APIStar** server ملا۔ اس میں تقریباً وہ سب کچھ تھا جو میں تلاش کر رہا تھا اور اس کا ایک بہترین ڈیزائن تھا۔ |
||||
|
|
||||
|
یہ parameters اور requests declare کرنے کے لیے Python type hints استعمال کرنے والے framework کے پہلے implementations میں سے ایک تھا جو میں نے کبھی دیکھا (NestJS اور Molten سے پہلے)۔ مجھے یہ تقریباً Hug کے ساتھ ہی ملا۔ لیکن APIStar نے OpenAPI standard استعمال کیا۔ |
||||
|
|
||||
|
اس میں کئی جگہوں پر ایک ہی type hints کی بنیاد پر خودکار data validation، data serialization اور OpenAPI schema generation تھی۔ |
||||
|
|
||||
|
Body schema definitions Pydantic کی طرح وہی Python type hints استعمال نہیں کرتی تھیں، یہ Marshmallow سے زیادہ ملتی جلتی تھیں، تو editor support اتنا اچھا نہ ہوتا، لیکن پھر بھی APIStar دستیاب بہترین آپشن تھا۔ |
||||
|
|
||||
|
اس وقت اس کے بہترین performance benchmarks تھے (صرف Starlette سے پیچھے)۔ |
||||
|
|
||||
|
شروع میں، اس کے پاس خودکار API documentation web UI نہیں تھا، لیکن مجھے معلوم تھا کہ میں اس میں Swagger UI شامل کر سکتا ہوں۔ |
||||
|
|
||||
|
اس کا dependency injection system تھا۔ اسے components کو پہلے سے register کرنا ضروری تھا، جیسے اوپر بیان کیے گئے دوسرے tools۔ لیکن پھر بھی، یہ ایک بہترین feature تھا۔ |
||||
|
|
||||
|
میں اسے کسی مکمل project میں استعمال نہیں کر سکا، کیونکہ اس میں security integration نہیں تھا، تو میں Flask-apispec پر مبنی full-stack generators کی تمام features کو replace نہیں کر سکتا تھا۔ میرے projects کے backlog میں وہ functionality شامل کرنے والی pull request بنانا تھا۔ |
||||
|
|
||||
|
لیکن پھر، project کی توجہ بدل گئی۔ |
||||
|
|
||||
|
یہ اب API web framework نہیں رہا، کیونکہ بانی کو Starlette پر توجہ مرکوز کرنی تھی۔ |
||||
|
|
||||
|
اب APIStar OpenAPI specifications کو validate کرنے والے tools کا مجموعہ ہے، web framework نہیں۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
APIStar Tom Christie نے بنایا تھا۔ وہی شخص جس نے بنایا: |
||||
|
|
||||
|
* Django REST Framework |
||||
|
* Starlette (جس پر **FastAPI** مبنی ہے) |
||||
|
* Uvicorn (جو Starlette اور **FastAPI** استعمال کرتے ہیں) |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// check | **FastAPI** کو تحریک دی |
||||
|
|
||||
|
موجود ہونے کی۔ |
||||
|
|
||||
|
ایک ہی Python types کے ساتھ متعدد چیزیں (data validation، serialization اور documentation) declare کرنے کا آئیڈیا، جو ساتھ ہی بہترین editor support بھی فراہم کرے، ایک شاندار آئیڈیا تھا۔ |
||||
|
|
||||
|
اور لمبے عرصے تک ملتا جلتا framework تلاش کرنے اور بہت سے مختلف متبادل ٹیسٹ کرنے کے بعد، APIStar دستیاب بہترین آپشن تھا۔ |
||||
|
|
||||
|
پھر APIStar ایک server کے طور پر بند ہو گیا اور Starlette بنایا گیا، اور ایسے system کے لیے ایک نئی بہتر بنیاد تھا۔ یہ **FastAPI** بنانے کی حتمی تحریک تھی۔ |
||||
|
|
||||
|
میں **FastAPI** کو APIStar کا "روحانی جانشین" سمجھتا ہوں، جبکہ ان تمام پچھلے tools سے سیکھے گئے سبق کی بنیاد پر features، typing system، اور دوسرے حصوں کو بہتر اور بڑھاتے ہوئے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## **FastAPI** کے ذریعے استعمال شدہ { #used-by-fastapi } |
||||
|
|
||||
|
### [Pydantic](https://docs.pydantic.dev/) { #pydantic } |
||||
|
|
||||
|
Pydantic ایک library ہے جو Python type hints کی بنیاد پر data validation، serialization اور documentation (JSON Schema استعمال کرتے ہوئے) define کرتی ہے۔ |
||||
|
|
||||
|
یہ اسے انتہائی بدیہی بناتا ہے۔ |
||||
|
|
||||
|
یہ Marshmallow سے قابل موازنہ ہے۔ حالانکہ benchmarks میں یہ Marshmallow سے تیز ہے۔ اور چونکہ یہ وہی Python type hints پر مبنی ہے، editor support بہترین ہے۔ |
||||
|
|
||||
|
/// check | **FastAPI** اسے استعمال کرتا ہے |
||||
|
|
||||
|
تمام data validation، data serialization اور خودکار model documentation (JSON Schema پر مبنی) سنبھالنے کے لیے۔ |
||||
|
|
||||
|
**FastAPI** پھر وہ JSON Schema data لے کر OpenAPI میں ڈالتا ہے، اس کے علاوہ جو کچھ اور یہ کرتا ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### [Starlette](https://www.starlette.dev/) { #starlette } |
||||
|
|
||||
|
Starlette ایک ہلکا پھلکا <dfn title="The new standard for building asynchronous Python web applications">ASGI</dfn> framework/toolkit ہے، جو اعلیٰ performance asyncio services بنانے کے لیے مثالی ہے۔ |
||||
|
|
||||
|
یہ بہت سادہ اور بدیہی ہے۔ اسے آسانی سے قابل توسیع، اور ماڈیولر اجزاء کے ساتھ ڈیزائن کیا گیا ہے۔ |
||||
|
|
||||
|
اس کے پاس ہے: |
||||
|
|
||||
|
* سنجیدگی سے شاندار performance۔ |
||||
|
* WebSocket support۔ |
||||
|
* In-process background tasks۔ |
||||
|
* Startup اور shutdown events۔ |
||||
|
* HTTPX پر مبنی Test client۔ |
||||
|
* CORS، GZip، Static Files، Streaming responses۔ |
||||
|
* Session اور Cookie support۔ |
||||
|
* 100% test coverage۔ |
||||
|
* 100% type annotated codebase۔ |
||||
|
* بہت کم hard dependencies۔ |
||||
|
|
||||
|
Starlette فی الحال ٹیسٹ شدہ تیز ترین Python framework ہے۔ صرف Uvicorn سے پیچھے، جو framework نہیں بلکہ server ہے۔ |
||||
|
|
||||
|
Starlette تمام بنیادی web microframework functionality فراہم کرتا ہے۔ |
||||
|
|
||||
|
لیکن یہ خودکار data validation، serialization یا documentation فراہم نہیں کرتا۔ |
||||
|
|
||||
|
یہ ان بنیادی چیزوں میں سے ایک ہے جو **FastAPI** اوپر سے شامل کرتا ہے، سب Python type hints پر مبنی (Pydantic استعمال کرتے ہوئے)۔ یہ، اور dependency injection system، security utilities، OpenAPI schema generation وغیرہ۔ |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
ASGI ایک نیا "standard" ہے جو Django core ٹیم کے ممبران develop کر رہے ہیں۔ یہ ابھی تک "Python standard" (PEP) نہیں ہے، حالانکہ وہ اس کے عمل میں ہیں۔ |
||||
|
|
||||
|
تاہم، یہ پہلے سے کئی tools کے ذریعے "standard" کے طور پر استعمال ہو رہا ہے۔ یہ interoperability کو بہت بہتر بناتا ہے، کیونکہ آپ Uvicorn کو کسی بھی دوسرے ASGI server (جیسے Daphne یا Hypercorn) سے بدل سکتے ہیں، یا ASGI compatible tools شامل کر سکتے ہیں، جیسے `python-socketio`۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// check | **FastAPI** اسے استعمال کرتا ہے |
||||
|
|
||||
|
تمام بنیادی web حصوں کو سنبھالنے کے لیے۔ اوپر features شامل کرتے ہوئے۔ |
||||
|
|
||||
|
`FastAPI` class خود براہ راست `Starlette` class سے inherit کرتی ہے۔ |
||||
|
|
||||
|
تو جو کچھ بھی آپ Starlette کے ساتھ کر سکتے ہیں، آپ براہ راست **FastAPI** کے ساتھ کر سکتے ہیں، کیونکہ یہ بنیادی طور پر Starlette ہے مگر طاقتور۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### [Uvicorn](https://www.uvicorn.dev/) { #uvicorn } |
||||
|
|
||||
|
Uvicorn ایک بجلی کی رفتار والا ASGI server ہے، uvloop اور httptools پر مبنی۔ |
||||
|
|
||||
|
یہ web framework نہیں بلکہ server ہے۔ مثلاً، یہ paths سے routing کے tools فراہم نہیں کرتا۔ یہ وہ چیز ہے جو Starlette (یا **FastAPI**) جیسا framework اوپر فراہم کرتا ہے۔ |
||||
|
|
||||
|
یہ Starlette اور **FastAPI** کے لیے تجویز کردہ server ہے۔ |
||||
|
|
||||
|
/// check | **FastAPI** اسے تجویز کرتا ہے بطور |
||||
|
|
||||
|
**FastAPI** applications چلانے کا بنیادی web server۔ |
||||
|
|
||||
|
آپ `--workers` command line option بھی استعمال کر سکتے ہیں تاکہ asynchronous multi-process server ہو۔ |
||||
|
|
||||
|
مزید تفصیلات [Deployment](deployment/index.md) سیکشن میں دیکھیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Benchmarks اور رفتار { #benchmarks-and-speed } |
||||
|
|
||||
|
Uvicorn، Starlette اور FastAPI کے درمیان فرق سمجھنے، موازنہ کرنے اور دیکھنے کے لیے [Benchmarks](benchmarks.md) کا سیکشن دیکھیں۔ |
||||
@ -0,0 +1,444 @@ |
|||||
|
# Concurrency اور async / await { #concurrency-and-async-await } |
||||
|
|
||||
|
*path operation functions* کے لیے `async def` syntax کے بارے میں تفصیلات اور asynchronous code، concurrency، اور parallelism کا پس منظر۔ |
||||
|
|
||||
|
## جلدی میں ہیں؟ { #in-a-hurry } |
||||
|
|
||||
|
<abbr title="too long; didn't read"><strong>TL;DR:</strong></abbr> |
||||
|
|
||||
|
اگر آپ third party libraries استعمال کر رہے ہیں جو آپ سے `await` کے ساتھ call کرنے کو کہتی ہیں، جیسے: |
||||
|
|
||||
|
```Python |
||||
|
results = await some_library() |
||||
|
``` |
||||
|
|
||||
|
تو اپنے *path operation functions* کو `async def` کے ساتھ declare کریں جیسے: |
||||
|
|
||||
|
```Python hl_lines="2" |
||||
|
@app.get('/') |
||||
|
async def read_results(): |
||||
|
results = await some_library() |
||||
|
return results |
||||
|
``` |
||||
|
|
||||
|
/// note | نوٹ |
||||
|
|
||||
|
آپ `await` صرف `async def` سے بنائے گئے functions کے اندر استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
اگر آپ کوئی third party library استعمال کر رہے ہیں جو کسی چیز سے communicate کرتی ہے (database، API، file system وغیرہ) اور `await` کے استعمال کی سہولت نہیں رکھتی (فی الحال زیادہ تر database libraries کے ساتھ یہی صورتحال ہے)، تو اپنے *path operation functions* کو عام طریقے سے صرف `def` کے ساتھ declare کریں، جیسے: |
||||
|
|
||||
|
```Python hl_lines="2" |
||||
|
@app.get('/') |
||||
|
def results(): |
||||
|
results = some_library() |
||||
|
return results |
||||
|
``` |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
اگر آپ کی application کو (کسی بھی طرح) کسی اور چیز سے communicate کرکے اس کے جواب کا انتظار نہیں کرنا ہے، تو `async def` استعمال کریں، چاہے آپ کو اندر `await` استعمال کرنے کی ضرورت نہ ہو۔ |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
اگر آپ کو نہیں معلوم، تو عام `def` استعمال کریں۔ |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
**نوٹ**: آپ اپنے *path operation functions* میں `def` اور `async def` کو جتنا چاہیں ملا جلا کر استعمال کر سکتے ہیں اور ہر ایک کو اپنی بہترین ضرورت کے مطابق define کر سکتے ہیں۔ FastAPI ان کے ساتھ صحیح طریقے سے کام کرے گا۔ |
||||
|
|
||||
|
بہرحال، اوپر کے کسی بھی معاملے میں، FastAPI پھر بھی asynchronously کام کرے گا اور انتہائی تیز ہوگا۔ |
||||
|
|
||||
|
لیکن اوپر دیے گئے اقدامات پر عمل کرنے سے، یہ کچھ performance optimizations کر سکے گا۔ |
||||
|
|
||||
|
## تکنیکی تفصیلات { #technical-details } |
||||
|
|
||||
|
Python کے جدید ورژنز **"asynchronous code"** کی سہولت فراہم کرتے ہیں جسے **"coroutines"** کہتے ہیں، **`async` اور `await`** syntax کے ساتھ۔ |
||||
|
|
||||
|
آئیے اس جملے کو نیچے دیے گئے حصوں میں تفصیل سے دیکھتے ہیں: |
||||
|
|
||||
|
* **Asynchronous Code** |
||||
|
* **`async` اور `await`** |
||||
|
* **Coroutines** |
||||
|
|
||||
|
## Asynchronous Code { #asynchronous-code } |
||||
|
|
||||
|
Asynchronous code کا مطلب صرف یہ ہے کہ زبان 💬 کے پاس computer / program 🤖 کو یہ بتانے کا ایک طریقہ ہے کہ code میں کسی مقام پر، اسے 🤖 کسی اور جگہ *کچھ اور* مکمل ہونے کا انتظار کرنا ہوگا۔ فرض کریں کہ وہ *کچھ اور* "slow-file" 📝 کہلاتا ہے۔ |
||||
|
|
||||
|
تو اس وقت کے دوران، computer جا کر کوئی اور کام کر سکتا ہے، جب تک "slow-file" 📝 مکمل ہوتا ہے۔ |
||||
|
|
||||
|
پھر computer / program 🤖 ہر بار واپس آئے گا جب اسے موقع ملے کیونکہ وہ دوبارہ انتظار میں ہے، یا جب بھی اس 🤖 نے اس وقت تک کا سارا کام مکمل کر لیا ہو۔ اور یہ 🤖 دیکھے گا کہ جن tasks کا انتظار تھا ان میں سے کوئی مکمل ہو چکا ہے، اور جو کچھ اسے کرنا تھا وہ کرے گا۔ |
||||
|
|
||||
|
پھر، یہ 🤖 مکمل ہونے والا پہلا task لیتا ہے (فرض کریں ہمارا "slow-file" 📝) اور جو کچھ اسے اس کے ساتھ کرنا تھا وہ جاری رکھتا ہے۔ |
||||
|
|
||||
|
وہ "کسی اور چیز کا انتظار" عام طور پر <abbr title="Input and Output">I/O</abbr> operations کی طرف اشارہ کرتا ہے جو نسبتاً "سست" ہوتے ہیں (processor اور RAM memory کی رفتار کے مقابلے میں)، جیسے انتظار کرنا: |
||||
|
|
||||
|
* client کے ذریعے network سے بھیجے جانے والے data کا |
||||
|
* آپ کے program کے ذریعے بھیجے گئے data کا client تک network سے پہنچنے کا |
||||
|
* disk پر فائل کے مواد کو system کے ذریعے پڑھ کر آپ کے program کو دینے کا |
||||
|
* آپ کے program نے system کو جو مواد دیا اسے disk پر لکھنے کا |
||||
|
* ایک remote API operation کا |
||||
|
* ایک database operation مکمل ہونے کا |
||||
|
* ایک database query کے نتائج واپس آنے کا |
||||
|
* وغیرہ۔ |
||||
|
|
||||
|
چونکہ execution time زیادہ تر <abbr title="Input and Output">I/O</abbr> operations کے انتظار میں صرف ہوتا ہے، انہیں "I/O bound" operations کہتے ہیں۔ |
||||
|
|
||||
|
اسے "asynchronous" اس لیے کہتے ہیں کیونکہ computer / program کو سست task کے ساتھ "synchronized" نہیں رہنا پڑتا، task مکمل ہونے کے صحیح لمحے کا انتظار کرتے ہوئے کچھ نہ کرتے ہوئے، تاکہ task کا نتیجہ لے کر کام جاری رکھ سکے۔ |
||||
|
|
||||
|
اس کی بجائے، ایک "asynchronous" system ہونے کی وجہ سے، ایک بار مکمل ہونے کے بعد، task تھوڑی دیر (کچھ microseconds) قطار میں انتظار کر سکتا ہے جب تک computer / program جو بھی کام کر رہا تھا وہ مکمل کرے، اور پھر واپس آ کر نتائج لے اور ان کے ساتھ کام جاری رکھے۔ |
||||
|
|
||||
|
"Synchronous" ("asynchronous" کے برعکس) کے لیے عام طور پر "sequential" کی اصطلاح بھی استعمال ہوتی ہے، کیونکہ computer / program تمام مراحل کو ترتیب سے follow کرتا ہے کسی مختلف task پر جانے سے پہلے، چاہے ان مراحل میں انتظار شامل ہو۔ |
||||
|
|
||||
|
### Concurrency اور برگرز { #concurrency-and-burgers } |
||||
|
|
||||
|
اوپر بیان کردہ **asynchronous** code کے اس تصور کو بعض اوقات **"concurrency"** بھی کہا جاتا ہے۔ یہ **"parallelism"** سے مختلف ہے۔ |
||||
|
|
||||
|
**Concurrency** اور **parallelism** دونوں کا تعلق "مختلف چیزوں کا کم و بیش ایک ہی وقت میں ہونا" سے ہے۔ |
||||
|
|
||||
|
لیکن *concurrency* اور *parallelism* کے درمیان تفصیلات کافی مختلف ہیں۔ |
||||
|
|
||||
|
فرق سمجھنے کے لیے، برگرز کے بارے میں یہ کہانی تصور کریں: |
||||
|
|
||||
|
### Concurrent برگرز { #concurrent-burgers } |
||||
|
|
||||
|
آپ اپنے ساتھی کے ساتھ fast food لینے جاتے ہیں، آپ قطار میں کھڑے ہوتے ہیں جب کہ cashier آپ سے پہلے والے لوگوں کے آرڈرز لے رہا ہوتا ہے۔ 😍 |
||||
|
|
||||
|
<img src="/img/async/concurrent-burgers/concurrent-burgers-01.png" class="illustration"> |
||||
|
|
||||
|
پھر آپ کی باری آتی ہے، آپ اپنے ساتھی اور اپنے لیے 2 بہت عمدہ برگرز کا آرڈر دیتے ہیں۔ 🍔🍔 |
||||
|
|
||||
|
<img src="/img/async/concurrent-burgers/concurrent-burgers-02.png" class="illustration"> |
||||
|
|
||||
|
Cashier کچن میں باورچی کو کچھ کہتا ہے تاکہ انہیں معلوم ہو کہ آپ کے برگرز تیار کرنے ہیں (حالانکہ وہ ابھی پہلے والے گاہکوں کے برگرز تیار کر رہے ہیں)۔ |
||||
|
|
||||
|
<img src="/img/async/concurrent-burgers/concurrent-burgers-03.png" class="illustration"> |
||||
|
|
||||
|
آپ ادائیگی کرتے ہیں۔ 💸 |
||||
|
|
||||
|
Cashier آپ کو آپ کی باری کا نمبر دیتا ہے۔ |
||||
|
|
||||
|
<img src="/img/async/concurrent-burgers/concurrent-burgers-04.png" class="illustration"> |
||||
|
|
||||
|
جب آپ انتظار کر رہے ہوتے ہیں، آپ اپنے ساتھی کے ساتھ جا کر ایک میز چنتے ہیں، بیٹھتے ہیں اور کافی دیر تک بات کرتے ہیں (کیونکہ آپ کے برگرز بہت عمدہ ہیں اور تیار ہونے میں وقت لگتا ہے)۔ |
||||
|
|
||||
|
جب آپ اپنے ساتھی کے ساتھ میز پر بیٹھے برگرز کا انتظار کر رہے ہوتے ہیں، آپ اس وقت کو یہ دیکھنے میں صرف کر سکتے ہیں کہ آپ کا ساتھی کتنا زبردست، خوبصورت اور ذہین ہے ✨😍✨۔ |
||||
|
|
||||
|
<img src="/img/async/concurrent-burgers/concurrent-burgers-05.png" class="illustration"> |
||||
|
|
||||
|
انتظار کرتے ہوئے اور اپنے ساتھی سے بات کرتے ہوئے، وقتاً فوقتاً آپ کاؤنٹر پر دکھائے جانے والے نمبر کو چیک کرتے ہیں کہ کیا آپ کی باری آ گئی ہے۔ |
||||
|
|
||||
|
پھر کسی وقت، آخرکار آپ کی باری آتی ہے۔ آپ کاؤنٹر پر جاتے ہیں، اپنے برگرز لیتے ہیں اور واپس میز پر آتے ہیں۔ |
||||
|
|
||||
|
<img src="/img/async/concurrent-burgers/concurrent-burgers-06.png" class="illustration"> |
||||
|
|
||||
|
آپ اور آپ کا ساتھی برگرز کھاتے ہیں اور اچھا وقت گزارتے ہیں۔ ✨ |
||||
|
|
||||
|
<img src="/img/async/concurrent-burgers/concurrent-burgers-07.png" class="illustration"> |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
خوبصورت تصاویر بنانے والی [Ketrina Thompson](https://www.instagram.com/ketrinadrawsalot)۔ 🎨 |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
تصور کریں کہ آپ اس کہانی میں computer / program 🤖 ہیں۔ |
||||
|
|
||||
|
جب آپ قطار میں ہوتے ہیں، آپ بس خالی بیٹھے 😴 اپنی باری کا انتظار کر رہے ہوتے ہیں، کوئی خاص "productive" کام نہیں کر رہے۔ لیکن قطار تیز ہے کیونکہ cashier صرف آرڈرز لے رہا ہے (تیار نہیں کر رہا)، تو یہ ٹھیک ہے۔ |
||||
|
|
||||
|
پھر جب آپ کی باری آتی ہے، آپ حقیقی "productive" کام کرتے ہیں، مینو پر غور کرتے ہیں، فیصلہ کرتے ہیں کہ آپ کیا چاہتے ہیں، اپنے ساتھی کی پسند لیتے ہیں، ادائیگی کرتے ہیں، چیک کرتے ہیں کہ آپ نے صحیح بل یا کارڈ دیا ہے، چیک کرتے ہیں کہ آپ سے صحیح رقم لی گئی ہے، چیک کرتے ہیں کہ آرڈر میں صحیح آئٹمز ہیں، وغیرہ۔ |
||||
|
|
||||
|
لیکن پھر، حالانکہ آپ کے پاس ابھی تک برگرز نہیں ہیں، cashier کے ساتھ آپ کا کام "روک" ⏸ پر ہے، کیونکہ آپ کو اپنے برگرز تیار ہونے کا انتظار 🕙 کرنا ہے۔ |
||||
|
|
||||
|
لیکن جیسے ہی آپ کاؤنٹر سے ہٹ کر اپنی باری کے نمبر کے ساتھ میز پر بیٹھتے ہیں، آپ اپنی توجہ 🔀 اپنے ساتھی کی طرف کر سکتے ہیں، اور اس پر "کام" ⏯ 🤓 کر سکتے ہیں۔ پھر آپ دوبارہ کچھ بہت "productive" کر رہے ہیں جیسے اپنے ساتھی سے فلرٹ کرنا 😍۔ |
||||
|
|
||||
|
پھر cashier 💁 کہتا ہے "میں نے برگرز تیار کر دیے" آپ کا نمبر کاؤنٹر کی display پر لگا کر، لیکن آپ پاگلوں کی طرح فوراً نہیں کودتے جب display نمبر آپ کی باری کے نمبر پر بدلتا ہے۔ آپ جانتے ہیں کہ کوئی آپ کے برگرز نہیں چرائے گا کیونکہ آپ کے پاس آپ کی باری کا نمبر ہے، اور ان کے پاس ان کا۔ |
||||
|
|
||||
|
تو آپ اپنے ساتھی کی کہانی مکمل ہونے کا انتظار کرتے ہیں (موجودہ کام ⏯ / task مکمل ہونا 🤓)، نرمی سے مسکراتے ہیں اور کہتے ہیں کہ آپ برگرز لینے جا رہے ہیں ⏸۔ |
||||
|
|
||||
|
پھر آپ کاؤنٹر 🔀 پر جاتے ہیں، اس ابتدائی task کی طرف جو اب مکمل ہو چکا ہے ⏯، برگرز لیتے ہیں، شکریہ کہتے ہیں اور انہیں میز پر لے آتے ہیں۔ یہ کاؤنٹر کے ساتھ تعامل کا وہ مرحلہ / task ختم کرتا ہے ⏹۔ یہ بدلے میں ایک نیا task شروع کرتا ہے، "برگرز کھانا" 🔀 ⏯، لیکن پچھلا "برگرز لینا" مکمل ہو چکا ہے ⏹۔ |
||||
|
|
||||
|
### Parallel برگرز { #parallel-burgers } |
||||
|
|
||||
|
اب تصور کریں کہ یہ "Concurrent برگرز" نہیں بلکہ "Parallel برگرز" ہیں۔ |
||||
|
|
||||
|
آپ اپنے ساتھی کے ساتھ parallel fast food لینے جاتے ہیں۔ |
||||
|
|
||||
|
آپ قطار میں کھڑے ہوتے ہیں جب کہ کئی (فرض کریں 8) cashiers جو بیک وقت باورچی بھی ہیں، آپ سے پہلے والے لوگوں کے آرڈرز لے رہے ہیں۔ |
||||
|
|
||||
|
آپ سے پہلے ہر شخص کاؤنٹر چھوڑنے سے پہلے اپنے برگرز تیار ہونے کا انتظار کر رہا ہے کیونکہ 8 cashiers میں سے ہر ایک اگلا آرڈر لینے سے پہلے برگر فوراً تیار کرتا ہے۔ |
||||
|
|
||||
|
<img src="/img/async/parallel-burgers/parallel-burgers-01.png" class="illustration"> |
||||
|
|
||||
|
پھر آخرکار آپ کی باری آتی ہے، آپ اپنے ساتھی اور اپنے لیے 2 بہت عمدہ برگرز کا آرڈر دیتے ہیں۔ |
||||
|
|
||||
|
آپ ادائیگی کرتے ہیں 💸۔ |
||||
|
|
||||
|
<img src="/img/async/parallel-burgers/parallel-burgers-02.png" class="illustration"> |
||||
|
|
||||
|
Cashier کچن میں جاتا ہے۔ |
||||
|
|
||||
|
آپ کاؤنٹر کے سامنے کھڑے رہتے ہیں 🕙، تاکہ کوئی اور آپ سے پہلے آپ کے برگرز نہ لے لے، کیونکہ باری کے نمبر نہیں ہیں۔ |
||||
|
|
||||
|
<img src="/img/async/parallel-burgers/parallel-burgers-03.png" class="illustration"> |
||||
|
|
||||
|
چونکہ آپ اور آپ کا ساتھی کسی کو اپنے سامنے آنے اور جب بھی وہ آئیں آپ کے برگرز لینے سے روکنے میں مصروف ہیں، آپ اپنے ساتھی پر توجہ نہیں دے سکتے۔ 😞 |
||||
|
|
||||
|
یہ "synchronous" کام ہے، آپ cashier/باورچی 👨🍳 کے ساتھ "synchronized" ہیں۔ آپ کو انتظار 🕙 کرنا ہے اور بالکل اس لمحے وہاں موجود ہونا ہے جب cashier/باورچی 👨🍳 برگرز مکمل کرے اور آپ کو دے، ورنہ کوئی اور لے سکتا ہے۔ |
||||
|
|
||||
|
<img src="/img/async/parallel-burgers/parallel-burgers-04.png" class="illustration"> |
||||
|
|
||||
|
پھر آپ کا cashier/باورچی 👨🍳 آخرکار آپ کے برگرز لے کر واپس آتا ہے، کاؤنٹر کے سامنے لمبے انتظار 🕙 کے بعد۔ |
||||
|
|
||||
|
<img src="/img/async/parallel-burgers/parallel-burgers-05.png" class="illustration"> |
||||
|
|
||||
|
آپ اپنے برگرز لیتے ہیں اور اپنے ساتھی کے ساتھ میز پر جاتے ہیں۔ |
||||
|
|
||||
|
آپ بس انہیں کھاتے ہیں، اور ہو گیا۔ ⏹ |
||||
|
|
||||
|
<img src="/img/async/parallel-burgers/parallel-burgers-06.png" class="illustration"> |
||||
|
|
||||
|
زیادہ بات چیت یا فلرٹنگ نہیں ہوئی کیونکہ زیادہ تر وقت کاؤنٹر کے سامنے انتظار 🕙 میں صرف ہوا۔ 😞 |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
خوبصورت تصاویر بنانے والی [Ketrina Thompson](https://www.instagram.com/ketrinadrawsalot)۔ 🎨 |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
Parallel برگرز کے اس منظرنامے میں، آپ ایک computer / program 🤖 ہیں جس کے دو processors ہیں (آپ اور آپ کا ساتھی)، دونوں انتظار 🕙 کر رہے ہیں اور اپنی توجہ ⏯ "کاؤنٹر پر انتظار" 🕙 میں لمبے عرصے تک لگائے ہوئے ہیں۔ |
||||
|
|
||||
|
Fast food store کے 8 processors (cashiers/باورچی) ہیں۔ جبکہ concurrent برگرز والے store میں شاید صرف 2 ہوں (ایک cashier اور ایک باورچی)۔ |
||||
|
|
||||
|
لیکن پھر بھی، حتمی تجربہ بہترین نہیں ہے۔ 😞 |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
یہ برگرز کی parallel مساوی کہانی ہوگی۔ 🍔 |
||||
|
|
||||
|
"حقیقی زندگی" کی مزید مثال کے لیے، ایک بینک تصور کریں۔ |
||||
|
|
||||
|
حال ہی تک، زیادہ تر بینکوں میں متعدد cashiers 👨💼👨💼👨💼👨💼 ہوتے تھے اور ایک بڑی قطار 🕙🕙🕙🕙🕙🕙🕙🕙۔ |
||||
|
|
||||
|
تمام cashiers ایک کے بعد ایک client کے ساتھ سارا کام کرتے 👨💼⏯۔ |
||||
|
|
||||
|
اور آپ کو قطار میں لمبا انتظار 🕙 کرنا ہوتا ہے ورنہ آپ اپنی باری کھو دیتے ہیں۔ |
||||
|
|
||||
|
آپ شاید اپنے ساتھی 😍 کو اپنے ساتھ بینک 🏦 میں کام کرانے نہیں لے جانا چاہیں گے۔ |
||||
|
|
||||
|
### برگرز کا نتیجہ { #burger-conclusion } |
||||
|
|
||||
|
"اپنے ساتھی کے ساتھ fast food برگرز" کے اس منظرنامے میں، چونکہ بہت زیادہ انتظار 🕙 ہے، concurrent system ⏸🔀⏯ رکھنا بہت زیادہ معنی رکھتا ہے۔ |
||||
|
|
||||
|
زیادہ تر web applications کے ساتھ یہی معاملہ ہے۔ |
||||
|
|
||||
|
بہت سارے، بہت سارے users، لیکن آپ کا server ان کے اتنے اچھے نہ ہونے والے connection سے requests بھیجنے کا انتظار 🕙 کر رہا ہے۔ |
||||
|
|
||||
|
اور پھر دوبارہ responses واپس آنے کا انتظار 🕙۔ |
||||
|
|
||||
|
یہ "انتظار" 🕙 microseconds میں ماپا جاتا ہے، لیکن پھر بھی، سب کو جمع کریں تو آخر میں بہت زیادہ انتظار ہوتا ہے۔ |
||||
|
|
||||
|
اسی لیے web APIs کے لیے asynchronous ⏸🔀⏯ code استعمال کرنا بہت معنی رکھتا ہے۔ |
||||
|
|
||||
|
اسی قسم کی asynchronicity نے NodeJS کو مقبول بنایا (حالانکہ NodeJS parallel نہیں ہے) اور یہی Go کی بطور programming language طاقت ہے۔ |
||||
|
|
||||
|
اور یہ وہی سطح کی performance ہے جو آپ کو **FastAPI** کے ساتھ ملتی ہے۔ |
||||
|
|
||||
|
اور چونکہ آپ parallelism اور asynchronicity دونوں بیک وقت حاصل کر سکتے ہیں، آپ کو زیادہ تر tested NodeJS frameworks سے زیادہ اور Go کے برابر performance ملتی ہے، جو C کے قریب ایک compiled language ہے [(یہ سب Starlette کی بدولت ہے)](https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1)۔ |
||||
|
|
||||
|
### کیا concurrency، parallelism سے بہتر ہے؟ { #is-concurrency-better-than-parallelism } |
||||
|
|
||||
|
نہیں! یہ کہانی کا سبق نہیں ہے۔ |
||||
|
|
||||
|
Concurrency، parallelism سے مختلف ہے۔ اور یہ ان **مخصوص** منظرناموں میں بہتر ہے جن میں بہت زیادہ انتظار شامل ہو۔ اس وجہ سے، یہ عام طور پر web application development کے لیے parallelism سے بہت بہتر ہے۔ لیکن ہر چیز کے لیے نہیں۔ |
||||
|
|
||||
|
تو اسے متوازن کرنے کے لیے، یہ مختصر کہانی تصور کریں: |
||||
|
|
||||
|
> آپ کو ایک بڑا، گندا گھر صاف کرنا ہے۔ |
||||
|
|
||||
|
*ہاں، یہی پوری کہانی ہے*۔ |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
کہیں بھی انتظار 🕙 نہیں ہے، بس گھر کی مختلف جگہوں پر بہت سارا کام کرنا ہے۔ |
||||
|
|
||||
|
آپ برگرز کی مثال کی طرح باریاں لے سکتے ہیں، پہلے بیٹھک، پھر کچن، لیکن چونکہ آپ کسی چیز کا انتظار 🕙 نہیں کر رہے، بس صفائی اور صفائی، تو باریاں کسی چیز پر اثر نہیں ڈالیں گی۔ |
||||
|
|
||||
|
باریوں (concurrency) کے ساتھ یا بغیر مکمل ہونے میں اتنا ہی وقت لگے گا اور آپ نے اتنا ہی کام کیا ہوگا۔ |
||||
|
|
||||
|
لیکن اس صورت میں، اگر آپ 8 سابقہ cashier/باورچی/اب صفائی والے لا سکتے، اور ہر ایک (آپ سمیت) گھر کا ایک حصہ صاف کر سکتا، تو آپ سارا کام **parallel** میں، اضافی مدد سے، بہت جلد مکمل کر سکتے تھے۔ |
||||
|
|
||||
|
اس منظرنامے میں، ہر صفائی کرنے والا (آپ سمیت) ایک processor ہوگا، جو اپنے حصے کا کام کر رہا ہوگا۔ |
||||
|
|
||||
|
اور چونکہ زیادہ تر execution time حقیقی کام میں صرف ہوتا ہے (انتظار کی بجائے)، اور computer میں کام ایک <abbr title="Central Processing Unit">CPU</abbr> کے ذریعے ہوتا ہے، وہ ان مسائل کو "CPU bound" کہتے ہیں۔ |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
CPU bound operations کی عام مثالیں وہ چیزیں ہیں جنہیں پیچیدہ ریاضیاتی processing کی ضرورت ہوتی ہے۔ |
||||
|
|
||||
|
مثال کے طور پر: |
||||
|
|
||||
|
* **Audio** یا **image processing**۔ |
||||
|
* **Computer vision**: ایک تصویر لاکھوں pixels پر مشتمل ہوتی ہے، ہر pixel میں 3 values / رنگ ہوتے ہیں، ان کی processing میں عام طور پر ان pixels پر بیک وقت کوئی حساب لگانا ہوتا ہے۔ |
||||
|
* **Machine Learning**: عام طور پر بہت سی "matrix" اور "vector" multiplications کی ضرورت ہوتی ہے۔ نمبروں سے بھری ایک بڑی spreadsheet کا تصور کریں اور ان سب کو بیک وقت ضرب دینا۔ |
||||
|
* **Deep Learning**: یہ Machine Learning کا ایک ذیلی شعبہ ہے، تو وہی اصول لاگو ہوتے ہیں۔ بس اتنا ہے کہ ضرب دینے کے لیے نمبروں کی ایک ہی spreadsheet نہیں بلکہ ایک بہت بڑا مجموعہ ہوتا ہے، اور بہت سے معاملات میں آپ ان models کو بنانے اور/یا استعمال کرنے کے لیے ایک خاص processor استعمال کرتے ہیں۔ |
||||
|
|
||||
|
### Concurrency + Parallelism: Web + Machine Learning { #concurrency-parallelism-web-machine-learning } |
||||
|
|
||||
|
**FastAPI** کے ساتھ آپ concurrency کا فائدہ اٹھا سکتے ہیں جو web development کے لیے بہت عام ہے (NodeJS کی وہی بنیادی کشش)۔ |
||||
|
|
||||
|
لیکن آپ parallelism اور multiprocessing (متعدد processes بیک وقت چلنا) کے فوائد کو بھی **CPU bound** workloads کے لیے استعمال کر سکتے ہیں جیسے Machine Learning systems۔ |
||||
|
|
||||
|
یہ، اور اس سادہ حقیقت کے ساتھ کہ Python **Data Science**، Machine Learning اور خاص طور پر Deep Learning کی بنیادی زبان ہے، FastAPI کو Data Science / Machine Learning web APIs اور applications کے لیے ایک بہت اچھا انتخاب بناتے ہیں (بہت سی دوسری چیزوں کے علاوہ)۔ |
||||
|
|
||||
|
production میں یہ parallelism کیسے حاصل کریں یہ جاننے کے لیے [Deployment](deployment/index.md) کا سیکشن دیکھیں۔ |
||||
|
|
||||
|
## `async` اور `await` { #async-and-await } |
||||
|
|
||||
|
Python کے جدید ورژنز میں asynchronous code define کرنے کا ایک بہت بدیہی طریقہ ہے۔ یہ اسے عام "sequential" code جیسا بناتا ہے اور صحیح لمحات پر آپ کے لیے "awaiting" کرتا ہے۔ |
||||
|
|
||||
|
جب کوئی operation ہو جو نتائج دینے سے پہلے انتظار کی ضرورت رکھتا ہو اور Python کی ان نئی features کی سہولت رکھتا ہو، آپ اسے اس طرح code کر سکتے ہیں: |
||||
|
|
||||
|
```Python |
||||
|
burgers = await get_burgers(2) |
||||
|
``` |
||||
|
|
||||
|
یہاں کلید `await` ہے۔ یہ Python کو بتاتا ہے کہ اسے `get_burgers(2)` کا اپنا کام 🕙 مکمل کرنے تک انتظار ⏸ کرنا ہے `burgers` میں نتائج محفوظ کرنے سے پہلے۔ اس کے ساتھ، Python جان لے گا کہ وہ اس دوران 🔀 ⏯ کچھ اور کام کر سکتا ہے (جیسے کوئی اور request وصول کرنا)۔ |
||||
|
|
||||
|
`await` کام کرنے کے لیے، اسے ایک ایسے function کے اندر ہونا ضروری ہے جو اس asynchronicity کی سہولت رکھتا ہو۔ ایسا کرنے کے لیے، بس اسے `async def` کے ساتھ declare کریں: |
||||
|
|
||||
|
```Python hl_lines="1" |
||||
|
async def get_burgers(number: int): |
||||
|
# Do some asynchronous stuff to create the burgers |
||||
|
return burgers |
||||
|
``` |
||||
|
|
||||
|
...`def` کی بجائے: |
||||
|
|
||||
|
```Python hl_lines="2" |
||||
|
# This is not asynchronous |
||||
|
def get_sequential_burgers(number: int): |
||||
|
# Do some sequential stuff to create the burgers |
||||
|
return burgers |
||||
|
``` |
||||
|
|
||||
|
`async def` کے ساتھ، Python جانتا ہے کہ اس function کے اندر اسے `await` expressions کا خیال رکھنا ہے، اور یہ کہ وہ اس function کی execution کو "روک" ⏸ کر واپس آنے سے پہلے 🔀 کچھ اور کام کر سکتا ہے۔ |
||||
|
|
||||
|
جب آپ کسی `async def` function کو call کرنا چاہیں، تو آپ کو اسے "await" کرنا ہوگا۔ تو یہ کام نہیں کرے گا: |
||||
|
|
||||
|
```Python |
||||
|
# This won't work, because get_burgers was defined with: async def |
||||
|
burgers = get_burgers(2) |
||||
|
``` |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
تو اگر آپ کوئی library استعمال کر رہے ہیں جو آپ سے `await` کے ساتھ call کرنے کو کہتی ہے، تو آپ کو اسے استعمال کرنے والے *path operation functions* کو `async def` کے ساتھ بنانا ہوگا، جیسے: |
||||
|
|
||||
|
```Python hl_lines="2-3" |
||||
|
@app.get('/burgers') |
||||
|
async def read_burgers(): |
||||
|
burgers = await get_burgers(2) |
||||
|
return burgers |
||||
|
``` |
||||
|
|
||||
|
### مزید تکنیکی تفصیلات { #more-technical-details } |
||||
|
|
||||
|
آپ نے غور کیا ہوگا کہ `await` صرف `async def` سے define کیے گئے functions کے اندر استعمال ہو سکتا ہے۔ |
||||
|
|
||||
|
لیکن ساتھ ہی، `async def` سے define کیے گئے functions کو "await" کرنا ضروری ہے۔ تو `async def` والے functions صرف `async def` سے define کیے گئے functions کے اندر ہی call ہو سکتے ہیں۔ |
||||
|
|
||||
|
تو انڈے اور مرغی کے بارے میں، آپ پہلا `async` function کیسے call کریں؟ |
||||
|
|
||||
|
اگر آپ **FastAPI** کے ساتھ کام کر رہے ہیں تو آپ کو اس کی فکر نہیں کرنی، کیونکہ وہ "پہلا" function آپ کا *path operation function* ہوگا، اور FastAPI جانے گا کہ صحیح کام کیسے کرنا ہے۔ |
||||
|
|
||||
|
لیکن اگر آپ FastAPI کے بغیر `async` / `await` استعمال کرنا چاہیں، تو آپ ایسا بھی کر سکتے ہیں۔ |
||||
|
|
||||
|
### اپنا async code لکھیں { #write-your-own-async-code } |
||||
|
|
||||
|
Starlette (اور **FastAPI**) [AnyIO](https://anyio.readthedocs.io/en/stable/) پر مبنی ہیں، جو اسے Python کی standard library [asyncio](https://docs.python.org/3/library/asyncio-task.html) اور [Trio](https://trio.readthedocs.io/en/stable/) دونوں کے ساتھ compatible بناتا ہے۔ |
||||
|
|
||||
|
خاص طور پر، آپ اپنے advanced concurrency use cases کے لیے براہ راست [AnyIO](https://anyio.readthedocs.io/en/stable/) استعمال کر سکتے ہیں جنہیں آپ کے اپنے code میں مزید advanced patterns کی ضرورت ہو۔ |
||||
|
|
||||
|
اور اگر آپ FastAPI استعمال نہیں بھی کر رہے ہوتے، تو بھی آپ [AnyIO](https://anyio.readthedocs.io/en/stable/) کے ساتھ اپنی async applications لکھ سکتے تھے جو بہت compatible ہوں اور اس کے فوائد حاصل کریں (مثلاً *structured concurrency*)۔ |
||||
|
|
||||
|
میں نے AnyIO کے اوپر ایک اور library بنائی ہے، ایک پتلی layer کے طور پر، type annotations کو تھوڑا بہتر بنانے اور بہتر **autocompletion**، **inline errors** وغیرہ حاصل کرنے کے لیے۔ اس میں ایک دوستانہ تعارف اور tutorial بھی ہے جو آپ کو **سمجھنے** اور **اپنا async code** لکھنے میں مدد کرے: [Asyncer](https://asyncer.tiangolo.com/)۔ یہ خاص طور پر مفید ہوگا اگر آپ کو **async code کو regular** (blocking/synchronous) code کے ساتھ ملانے کی ضرورت ہو۔ |
||||
|
|
||||
|
### Asynchronous code کی دوسری شکلیں { #other-forms-of-asynchronous-code } |
||||
|
|
||||
|
`async` اور `await` استعمال کرنے کا یہ انداز زبان میں نسبتاً نیا ہے۔ |
||||
|
|
||||
|
لیکن یہ asynchronous code کے ساتھ کام کرنا بہت آسان بناتا ہے۔ |
||||
|
|
||||
|
یہی syntax (یا تقریباً ایک جیسا) حال ہی میں JavaScript کے جدید ورژنز (Browser اور NodeJS میں) میں بھی شامل کیا گیا۔ |
||||
|
|
||||
|
لیکن اس سے پہلے، asynchronous code کو سنبھالنا کافی زیادہ پیچیدہ اور مشکل تھا۔ |
||||
|
|
||||
|
Python کے پچھلے ورژنز میں، آپ threads یا [Gevent](https://www.gevent.org/) استعمال کر سکتے تھے۔ لیکن code سمجھنے، debug کرنے، اور سوچنے میں بہت زیادہ پیچیدہ ہوتا ہے۔ |
||||
|
|
||||
|
NodeJS / Browser JavaScript کے پچھلے ورژنز میں، آپ "callbacks" استعمال کرتے۔ جو "callback hell" کی طرف لے جاتا ہے۔ |
||||
|
|
||||
|
## Coroutines { #coroutines } |
||||
|
|
||||
|
**Coroutine** بس اس چیز کے لیے ایک بہت فینسی اصطلاح ہے جو `async def` function واپس کرتا ہے۔ Python جانتا ہے کہ یہ ایک function جیسی چیز ہے، جو شروع ہو سکتی ہے اور کسی وقت ختم ہوگی، لیکن یہ اندرونی طور پر بھی ⏸ روکی جا سکتی ہے، جب بھی اس کے اندر `await` ہو۔ |
||||
|
|
||||
|
لیکن `async` اور `await` کے ساتھ asynchronous code استعمال کرنے کی یہ ساری functionality اکثر "coroutines" استعمال کرنا کہہ کر خلاصہ کی جاتی ہے۔ یہ Go کی بنیادی خصوصیت "Goroutines" سے قابل موازنہ ہے۔ |
||||
|
|
||||
|
## نتیجہ { #conclusion } |
||||
|
|
||||
|
آئیے اوپر والا وہی جملہ دوبارہ دیکھتے ہیں: |
||||
|
|
||||
|
> Python کے جدید ورژنز **"asynchronous code"** کی سہولت فراہم کرتے ہیں جسے **"coroutines"** کہتے ہیں، **`async` اور `await`** syntax کے ساتھ۔ |
||||
|
|
||||
|
اب یہ زیادہ سمجھ آنا چاہیے۔ ✨ |
||||
|
|
||||
|
یہی سب **FastAPI** کو (Starlette کے ذریعے) طاقت دیتا ہے اور اسے اتنی شاندار performance دیتا ہے۔ |
||||
|
|
||||
|
## انتہائی تکنیکی تفصیلات { #very-technical-details } |
||||
|
|
||||
|
/// warning | انتباہ |
||||
|
|
||||
|
آپ شاید اسے چھوڑ سکتے ہیں۔ |
||||
|
|
||||
|
یہ بہت تکنیکی تفصیلات ہیں کہ **FastAPI** اندرونی طور پر کیسے کام کرتا ہے۔ |
||||
|
|
||||
|
اگر آپ کے پاس کافی تکنیکی علم ہے (coroutines، threads، blocking وغیرہ) اور آپ جاننا چاہتے ہیں کہ FastAPI `async def` بمقابلہ عام `def` کو کیسے سنبھالتا ہے، تو آگے بڑھیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### Path operation functions { #path-operation-functions } |
||||
|
|
||||
|
جب آپ *path operation function* کو `async def` کی بجائے عام `def` کے ساتھ declare کرتے ہیں، تو اسے ایک بیرونی threadpool میں چلایا جاتا ہے جس کا پھر await کیا جاتا ہے، براہ راست call کرنے کی بجائے (کیونکہ یہ server کو block کر دے گا)۔ |
||||
|
|
||||
|
اگر آپ کسی اور async framework سے آ رہے ہیں جو اوپر بیان کردہ طریقے سے کام نہیں کرتا اور آپ عام `def` کے ساتھ معمولی compute-only *path operation functions* define کرنے کے عادی ہیں تھوڑی سی performance بہتری (تقریباً 100 nanoseconds) کے لیے، تو براہ کرم نوٹ کریں کہ **FastAPI** میں اثر بالکل الٹا ہوگا۔ ان صورتوں میں، `async def` استعمال کرنا بہتر ہے جب تک کہ آپ کے *path operation functions* ایسا code استعمال نہ کریں جو blocking <abbr title="Input/Output: disk reading or writing, network communications.">I/O</abbr> کرتا ہو۔ |
||||
|
|
||||
|
پھر بھی، دونوں صورتوں میں، امکان ہے کہ **FastAPI** آپ کے پچھلے framework سے [پھر بھی تیز](index.md#performance) ہوگا (یا کم از کم اس کے برابر)۔ |
||||
|
|
||||
|
### Dependencies { #dependencies } |
||||
|
|
||||
|
یہی [dependencies](tutorial/dependencies/index.md) پر بھی لاگو ہوتا ہے۔ اگر dependency ایک عام `def` function ہے `async def` کی بجائے، تو اسے بیرونی threadpool میں چلایا جاتا ہے۔ |
||||
|
|
||||
|
### Sub-dependencies { #sub-dependencies } |
||||
|
|
||||
|
آپ کے متعدد dependencies اور [sub-dependencies](tutorial/dependencies/sub-dependencies.md) ہو سکتے ہیں جو ایک دوسرے کی ضرورت رکھتے ہوں (function definitions کے parameters کے طور پر)، ان میں سے کچھ `async def` سے بنائے جا سکتے ہیں اور کچھ عام `def` سے۔ یہ پھر بھی کام کرے گا، اور عام `def` سے بنائے گئے ایک بیرونی thread (threadpool سے) پر call کیے جائیں گے "await" کیے جانے کی بجائے۔ |
||||
|
|
||||
|
### دوسرے utility functions { #other-utility-functions } |
||||
|
|
||||
|
کوئی بھی دوسرا utility function جسے آپ براہ راست call کرتے ہیں، عام `def` یا `async def` سے بنایا جا سکتا ہے اور FastAPI اس پر اثر نہیں ڈالے گا جس طرح آپ اسے call کرتے ہیں۔ |
||||
|
|
||||
|
یہ ان functions کے برعکس ہے جو FastAPI آپ کے لیے call کرتا ہے: *path operation functions* اور dependencies۔ |
||||
|
|
||||
|
اگر آپ کا utility function ایک عام `def` والا function ہے، تو اسے براہ راست call کیا جائے گا (جیسا کہ آپ اسے اپنے code میں لکھتے ہیں)، threadpool میں نہیں، اگر function `async def` سے بنایا گیا ہے تو آپ کو اس function کو اپنے code میں call کرتے وقت `await` کرنا چاہیے۔ |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
دوبارہ، یہ بہت تکنیکی تفصیلات ہیں جو شاید مفید ہوں اگر آپ انہیں تلاش کرتے ہوئے آئے ہیں۔ |
||||
|
|
||||
|
ورنہ، آپ اوپر والے سیکشن کی ہدایات سے ٹھیک ہونے چاہئیں: <a href="#in-a-hurry">جلدی میں ہیں؟</a> |
||||
@ -0,0 +1,34 @@ |
|||||
|
# Benchmarks { #benchmarks } |
||||
|
|
||||
|
آزاد TechEmpower benchmarks ظاہر کرتے ہیں کہ Uvicorn کے تحت چلنے والی **FastAPI** applications [دستیاب تیز ترین Python frameworks میں سے ایک](https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7) ہیں، صرف Starlette اور Uvicorn سے پیچھے (جو FastAPI اندرونی طور پر استعمال کرتا ہے)۔ |
||||
|
|
||||
|
لیکن benchmarks اور موازنے دیکھتے وقت آپ کو درج ذیل باتیں ذہن میں رکھنی چاہئیں۔ |
||||
|
|
||||
|
## Benchmarks اور رفتار { #benchmarks-and-speed } |
||||
|
|
||||
|
جب آپ benchmarks دیکھتے ہیں، تو عام طور پر مختلف اقسام کے کئی tools کو مساوی کے طور پر موازنہ کیا جاتا ہے۔ |
||||
|
|
||||
|
خاص طور پر، Uvicorn، Starlette اور FastAPI کو ایک ساتھ (بہت سے دوسرے tools کے درمیان) موازنے میں دیکھنا۔ |
||||
|
|
||||
|
tool جتنا آسان مسئلہ حل کرتا ہے، اتنی بہتر performance دیتا ہے۔ اور زیادہ تر benchmarks tool کی فراہم کردہ اضافی features کو ٹیسٹ نہیں کرتے۔ |
||||
|
|
||||
|
درجہ بندی اس طرح ہے: |
||||
|
|
||||
|
* **Uvicorn**: ایک ASGI server |
||||
|
* **Starlette**: (Uvicorn استعمال کرتا ہے) ایک web microframework |
||||
|
* **FastAPI**: (Starlette استعمال کرتا ہے) ایک API microframework جس میں APIs بنانے کے لیے کئی اضافی features ہیں، data validation وغیرہ کے ساتھ۔ |
||||
|
|
||||
|
* **Uvicorn**: |
||||
|
* سب سے بہترین performance ہوگی، کیونکہ server کے علاوہ اس میں زیادہ اضافی code نہیں ہے۔ |
||||
|
* آپ براہ راست Uvicorn میں application نہیں لکھیں گے۔ اس کا مطلب ہوگا کہ آپ کے code میں کم از کم وہ سارا code شامل ہو جو Starlette (یا **FastAPI**) فراہم کرتا ہے۔ اور اگر آپ ایسا کریں، تو آپ کی حتمی application میں بھی وہی overhead ہوگا جیسا framework استعمال کرنے اور app code اور bugs کو کم سے کم رکھنے میں ہوتا۔ |
||||
|
* اگر آپ Uvicorn کا موازنہ کر رہے ہیں، تو اسے Daphne، Hypercorn، uWSGI وغیرہ سے موازنہ کریں۔ Application servers۔ |
||||
|
* **Starlette**: |
||||
|
* Uvicorn کے بعد اگلی بہترین performance ہوگی۔ درحقیقت، Starlette چلنے کے لیے Uvicorn استعمال کرتا ہے۔ تو یہ شاید صرف مزید code execute کرنے کی وجہ سے Uvicorn سے "سست" ہو سکتا ہے۔ |
||||
|
* لیکن یہ آپ کو سادہ web applications بنانے کے tools فراہم کرتا ہے، paths پر مبنی routing وغیرہ کے ساتھ۔ |
||||
|
* اگر آپ Starlette کا موازنہ کر رہے ہیں، تو اسے Sanic، Flask، Django وغیرہ سے موازنہ کریں۔ Web frameworks (یا microframeworks)۔ |
||||
|
* **FastAPI**: |
||||
|
* جس طرح Starlette، Uvicorn استعمال کرتا ہے اور اس سے تیز نہیں ہو سکتا، **FastAPI** Starlette استعمال کرتا ہے، تو یہ اس سے تیز نہیں ہو سکتا۔ |
||||
|
* FastAPI، Starlette کے اوپر مزید features فراہم کرتا ہے۔ وہ features جن کی آپ کو APIs بناتے وقت تقریباً ہمیشہ ضرورت ہوتی ہے، جیسے data validation اور serialization۔ اور اسے استعمال کرنے سے آپ کو خودکار documentation مفت میں ملتی ہے (خودکار documentation چلتی applications میں overhead بھی نہیں ڈالتی، یہ startup پر generate ہوتی ہے)۔ |
||||
|
* اگر آپ نے FastAPI استعمال نہ کیا ہوتا اور براہ راست Starlette (یا کوئی اور tool جیسے Sanic، Flask، Responder وغیرہ) استعمال کیا ہوتا تو آپ کو ساری data validation اور serialization خود implement کرنی ہوتی۔ تو آپ کی حتمی application میں پھر بھی وہی overhead ہوتا جیسا FastAPI استعمال کرنے میں ہوتا۔ اور بہت سے معاملات میں، یہ data validation اور serialization applications میں لکھے جانے والے code کا سب سے بڑا حصہ ہوتی ہے۔ |
||||
|
* تو FastAPI استعمال کرکے آپ development time، bugs، code کی لائنیں بچا رہے ہیں، اور شاید آپ کو وہی performance (یا بہتر) ملے گی جو آپ کو اسے استعمال نہ کرنے پر ملتی (کیونکہ آپ کو یہ سب اپنے code میں implement کرنا ہوتا)۔ |
||||
|
* اگر آپ FastAPI کا موازنہ کر رہے ہیں، تو اسے کسی web application framework (یا tools کے مجموعے) سے موازنہ کریں جو data validation، serialization اور documentation فراہم کرتا ہو، جیسے Flask-apispec، NestJS، Molten وغیرہ۔ وہ frameworks جن میں مربوط خودکار data validation، serialization اور documentation شامل ہو۔ |
||||
@ -0,0 +1,261 @@ |
|||||
|
# ترقی - تعاون |
||||
|
|
||||
|
پہلے، آپ [FastAPI کی مدد کریں اور مدد حاصل کریں](help-fastapi.md) کے بنیادی طریقے دیکھنا چاہیں گے۔ |
||||
|
|
||||
|
## ترقی |
||||
|
|
||||
|
اگر آپ نے پہلے ہی [fastapi repository](https://github.com/fastapi/fastapi) clone کر لیا ہے اور code میں گہرائی سے جانا چاہتے ہیں، تو یہاں آپ کا ماحول ترتیب دینے کی کچھ ہدایات ہیں۔ |
||||
|
|
||||
|
### ضروریات install کریں |
||||
|
|
||||
|
Virtual environment بنائیں اور [`uv`](https://github.com/astral-sh/uv) کے ساتھ درکار packages install کریں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ uv sync --extra all |
||||
|
|
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
یہ تمام dependencies اور آپ کا مقامی FastAPI آپ کے مقامی ماحول میں install کر دے گا۔ |
||||
|
|
||||
|
### اپنا مقامی FastAPI استعمال کریں |
||||
|
|
||||
|
اگر آپ ایک Python فائل بناتے ہیں جو FastAPI import اور استعمال کرتی ہے، اور اسے اپنے مقامی ماحول کے Python سے چلاتے ہیں، تو یہ آپ کا clone شدہ مقامی FastAPI source code استعمال کرے گا۔ |
||||
|
|
||||
|
اور اگر آپ اس مقامی FastAPI source code کو اپڈیٹ کرتے ہیں تو جب آپ وہ Python فائل دوبارہ چلائیں گے، یہ FastAPI کا وہ تازہ ورژن استعمال کرے گا جو آپ نے ابھی ترمیم کیا ہے۔ |
||||
|
|
||||
|
اس طرح، ہر تبدیلی ٹیسٹ کرنے کے لیے آپ کو اپنا مقامی ورژن "install" نہیں کرنا پڑتا۔ |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
یہ صرف تب ہوتا ہے جب آپ `pip install fastapi` براہ راست چلانے کی بجائے `uv sync --extra all` استعمال کرکے install کرتے ہیں۔ |
||||
|
|
||||
|
اس کی وجہ یہ ہے کہ `uv sync --extra all` بطور default FastAPI کا مقامی ورژن "editable" mode میں install کرتا ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### Code فارمیٹ کریں |
||||
|
|
||||
|
ایک script ہے جسے آپ چلا سکتے ہیں جو آپ کا سارا code فارمیٹ اور صاف کر دے گی: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ bash scripts/format.sh |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
یہ آپ کے تمام imports کو بھی خودکار طریقے سے ترتیب دے گی۔ |
||||
|
|
||||
|
## Tests |
||||
|
|
||||
|
ایک script ہے جسے آپ مقامی طور پر تمام code ٹیسٹ کرنے اور HTML میں coverage reports بنانے کے لیے چلا سکتے ہیں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ bash scripts/test-cov-html.sh |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
یہ command `./htmlcov/` directory بناتی ہے، اگر آپ `./htmlcov/index.html` فائل اپنے browser میں کھولیں، تو آپ انٹرایکٹو طریقے سے دیکھ سکتے ہیں کہ code کے کون سے حصے tests سے cover ہیں، اور کوئی حصہ رہ تو نہیں گیا۔ |
||||
|
|
||||
|
## Docs |
||||
|
|
||||
|
پہلے، یقینی بنائیں کہ آپ نے اوپر بیان کردہ طریقے سے اپنا ماحول ترتیب دیا ہے، جو تمام ضروریات install کر دے گا۔ |
||||
|
|
||||
|
### Docs لائیو |
||||
|
|
||||
|
مقامی ترقی کے دوران، ایک script ہے جو سائٹ بناتی ہے اور کسی بھی تبدیلی کو چیک کرتی ہے، لائیو ری لوڈنگ کے ساتھ: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ python ./scripts/docs.py live |
||||
|
|
||||
|
<span style="color: green;">[INFO]</span> Serving on http://127.0.0.1:8008 |
||||
|
<span style="color: green;">[INFO]</span> Start watching changes |
||||
|
<span style="color: green;">[INFO]</span> Start detecting changes |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
یہ documentation کو `http://127.0.0.1:8008` پر serve کرے گا۔ |
||||
|
|
||||
|
اس طرح، آپ documentation/source فائلوں میں ترمیم کر سکتے ہیں اور تبدیلیاں لائیو دیکھ سکتے ہیں۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
متبادل طور پر، آپ وہی اقدامات خود دستی طور پر کر سکتے ہیں جو script کرتی ہے۔ |
||||
|
|
||||
|
زبان کی directory میں جائیں، بنیادی docs کے لیے انگریزی میں یہ `docs/en/` پر ہے: |
||||
|
|
||||
|
```console |
||||
|
$ cd docs/en/ |
||||
|
``` |
||||
|
|
||||
|
پھر اس directory میں `mkdocs` چلائیں: |
||||
|
|
||||
|
```console |
||||
|
$ mkdocs serve --dev-addr 127.0.0.1:8008 |
||||
|
``` |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
#### Typer CLI (اختیاری) |
||||
|
|
||||
|
یہاں ہدایات آپ کو دکھاتی ہیں کہ `./scripts/docs.py` script کو `python` program کے ساتھ براہ راست کیسے استعمال کریں۔ |
||||
|
|
||||
|
لیکن آپ [Typer CLI](https://typer.tiangolo.com/typer-cli/) بھی استعمال کر سکتے ہیں، اور completion install کرنے کے بعد آپ کو اپنے terminal میں commands کے لیے autocompletion ملے گی۔ |
||||
|
|
||||
|
اگر آپ Typer CLI install کرتے ہیں، تو آپ اس کے ساتھ completion install کر سکتے ہیں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ typer --install-completion |
||||
|
|
||||
|
zsh completion installed in /home/user/.bashrc. |
||||
|
Completion will take effect once you restart the terminal. |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
### Docs کی ساخت |
||||
|
|
||||
|
Documentation [MkDocs](https://www.mkdocs.org/) استعمال کرتی ہے۔ |
||||
|
|
||||
|
اور `./scripts/docs.py` میں تراجم کو سنبھالنے کے لیے اضافی tools/scripts موجود ہیں۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
آپ کو `./scripts/docs.py` کا code دیکھنے کی ضرورت نہیں، آپ بس اسے command line میں استعمال کرتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
تمام documentation `./docs/en/` directory میں Markdown فارمیٹ میں ہے۔ |
||||
|
|
||||
|
بہت سے tutorials میں code blocks ہوتے ہیں۔ |
||||
|
|
||||
|
زیادہ تر معاملات میں، یہ code blocks مکمل applications ہیں جو جیسے ہیں ویسے چلائی جا سکتی ہیں۔ |
||||
|
|
||||
|
درحقیقت، وہ code blocks Markdown کے اندر نہیں لکھے جاتے، بلکہ `./docs_src/` directory میں Python فائلیں ہیں۔ |
||||
|
|
||||
|
اور وہ Python فائلیں سائٹ generate کرتے وقت documentation میں شامل/inject کی جاتی ہیں۔ |
||||
|
|
||||
|
### Tests کے لیے Docs |
||||
|
|
||||
|
زیادہ تر tests دراصل documentation میں موجود مثالی source فائلوں کے خلاف چلتے ہیں۔ |
||||
|
|
||||
|
اس سے یہ یقینی بنانے میں مدد ملتی ہے کہ: |
||||
|
|
||||
|
* Documentation تازہ ترین ہے۔ |
||||
|
* Documentation کی مثالیں جیسی ہیں ویسی چلائی جا سکتی ہیں۔ |
||||
|
* زیادہ تر features documentation سے cover ہیں، test coverage سے یقینی بنائی گئی ہیں۔ |
||||
|
|
||||
|
#### Apps اور docs بیک وقت |
||||
|
|
||||
|
اگر آپ مثالیں چلاتے ہیں، جیسے: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ fastapi dev tutorial001.py |
||||
|
|
||||
|
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
چونکہ Uvicorn بطور default port `8000` استعمال کرتا ہے، port `8008` پر documentation اس سے نہیں ٹکرائے گی۔ |
||||
|
|
||||
|
### تراجم |
||||
|
|
||||
|
تراجم میں مدد بہت زیادہ قدر کی جاتی ہے! اور یہ کمیونٹی کی مدد کے بغیر نہیں ہو سکتا۔ 🌎 🚀 |
||||
|
|
||||
|
ترجمے کی pull requests FastAPI ٹیم کی طرف سے ڈیزائن کردہ prompts سے رہنمائی حاصل کرنے والے LLMs اور ہر supported زبان کے لیے مقامی بولنے والوں کی کمیونٹی کے ساتھ مل کر بنائی جاتی ہیں۔ |
||||
|
|
||||
|
#### فی زبان LLM Prompt |
||||
|
|
||||
|
ہر زبان کی ایک directory ہے: [https://github.com/fastapi/fastapi/tree/master/docs](https://github.com/fastapi/fastapi/tree/master/docs)، اس میں آپ `llm-prompt.md` فائل دیکھ سکتے ہیں جس میں اس زبان کے لیے مخصوص prompt ہے۔ |
||||
|
|
||||
|
مثال کے طور پر، ہسپانوی کے لیے prompt یہاں ہے: [`docs/es/llm-prompt.md`](https://github.com/fastapi/fastapi/blob/master/docs/es/llm-prompt.md)۔ |
||||
|
|
||||
|
اگر آپ کو اپنی زبان میں غلطیاں نظر آئیں، تو آپ اپنی زبان کی فائل میں prompt کے لیے تجاویز دے سکتے ہیں، اور تبدیلیوں کے بعد ان مخصوص pages کی دوبارہ تخلیق کی درخواست کر سکتے ہیں۔ |
||||
|
|
||||
|
#### ترجمے کی PRs کا Review |
||||
|
|
||||
|
آپ اپنی زبان کے لیے موجودہ [pull requests](https://github.com/fastapi/fastapi/pulls) بھی چیک کر سکتے ہیں۔ آپ اپنی زبان کے label کے ساتھ pull requests فلٹر کر سکتے ہیں۔ مثال کے طور پر، ہسپانوی کے لیے label [`lang-es`](https://github.com/fastapi/fastapi/pulls?q=is%3Aopen+sort%3Aupdated-desc+label%3Alang-es+label%3Aawaiting-review) ہے۔ |
||||
|
|
||||
|
Pull request کا review کرتے وقت، بہتر ہے کہ اسی pull request میں تبدیلیاں تجویز نہ کریں، کیونکہ یہ LLM سے generate کیا گیا ہے، اور یہ یقینی بنانا ممکن نہیں ہوگا کہ چھوٹی انفرادی تبدیلیاں دوسرے ملتے جلتے حصوں میں نقل ہوں، یا وہی مواد دوبارہ ترجمہ کرتے وقت محفوظ رہیں۔ |
||||
|
|
||||
|
ترجمے کی PR میں تجاویز شامل کرنے کی بجائے، اس زبان کی LLM prompt فائل میں تجاویز دیں، ایک نئی PR میں۔ مثال کے طور پر، ہسپانوی کی LLM prompt فائل یہاں ہے: [`docs/es/llm-prompt.md`](https://github.com/fastapi/fastapi/blob/master/docs/es/llm-prompt.md)۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
[Pull request review شامل کرنے](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-request-reviews) کے بارے میں docs چیک کریں تاکہ اسے منظور یا تبدیلیوں کی درخواست کر سکیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
#### اپنی زبان کے لیے Notifications سبسکرائب کریں |
||||
|
|
||||
|
چیک کریں کہ آیا آپ کی زبان کے تراجم کی coordination کے لیے [GitHub Discussion](https://github.com/fastapi/fastapi/discussions/categories/translations) ہے۔ آپ اسے سبسکرائب کر سکتے ہیں، اور جب review کے لیے نئی pull request ہوگی، discussion میں خودکار تبصرہ شامل کیا جائے گا۔ |
||||
|
|
||||
|
آپ جس زبان کا ترجمہ کرنا چاہتے ہیں اس کا 2 حرفی code جاننے کے لیے [List of ISO 639-1 codes](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) کا جدول استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
#### نئی زبان کی درخواست |
||||
|
|
||||
|
فرض کریں کہ آپ ایسی زبان کے تراجم کی درخواست کرنا چاہتے ہیں جس کا ابھی تک ترجمہ نہیں ہوا، کوئی page بھی نہیں۔ مثال کے طور پر، لاطینی۔ |
||||
|
|
||||
|
* پہلا قدم یہ ہوگا کہ آپ 2 اور لوگ تلاش کریں جو آپ کے ساتھ اس زبان کے لیے ترجمے کی PRs کا review کرنے کو تیار ہوں۔ |
||||
|
* جب کم از کم 3 لوگ اس زبان کی دیکھ بھال میں مدد کا عہد کرنے کو تیار ہوں، تو آپ اگلے اقدامات جاری رکھ سکتے ہیں۔ |
||||
|
* Template کے مطابق نئی discussion بنائیں۔ |
||||
|
* اپنے ساتھ مدد کرنے والے 2 دوسرے لوگوں کو tag کریں، اور ان سے وہاں تصدیق کرنے کو کہیں کہ وہ مدد کریں گے۔ |
||||
|
|
||||
|
جب discussion میں کئی لوگ ہوں، FastAPI ٹیم اس کا جائزہ لے سکتی ہے اور اسے سرکاری ترجمہ بنا سکتی ہے۔ |
||||
|
|
||||
|
پھر docs خودکار طور پر LLMs کے ذریعے ترجمہ ہوں گے، اور مقامی بولنے والوں کی ٹیم ترجمے کا review کر سکتی ہے، اور LLM prompts کو بہتر بنانے میں مدد کر سکتی ہے۔ |
||||
|
|
||||
|
جب نیا ترجمہ ہوگا، مثال کے طور پر اگر docs اپڈیٹ ہوں یا نیا سیکشن ہو، تو اسی discussion میں review کے لیے نئے ترجمے کے link کے ساتھ تبصرہ آئے گا۔ |
||||
|
|
||||
|
## خودکار Code اور AI |
||||
|
|
||||
|
آپ کو ہر وہ tool استعمال کرنے کی ترغیب دی جاتی ہے جو آپ چاہیں تاکہ اپنا کام کریں اور جتنا ہو سکے مؤثر طریقے سے تعاون کریں، بشمول AI (LLM) tools وغیرہ۔ تاہم، تعاون میں بامعنی انسانی مداخلت، فیصلے، سیاق و سباق وغیرہ ہونا چاہیے۔ |
||||
|
|
||||
|
اگر PR میں لگائی گئی **انسانی محنت**، جیسے LLM prompts لکھنا، اس **محنت سے کم** ہے جو ہمیں اسے **review** کرنے میں لگانی ہوگی، تو براہ کرم PR **جمع نہ کریں**۔ |
||||
|
|
||||
|
اس طرح سوچیں: ہم خود LLM prompts لکھ سکتے ہیں یا خودکار tools چلا سکتے ہیں، اور یہ بیرونی PRs کا review کرنے سے تیز ہوگا۔ |
||||
|
|
||||
|
### خودکار اور AI PRs بند کرنا |
||||
|
|
||||
|
اگر ہمیں ایسی PRs نظر آئیں جو AI سے generate کی گئی یا اسی طرح خودکار لگتی ہیں، تو ہم انہیں flag کرکے بند کر دیں گے۔ |
||||
|
|
||||
|
یہی تبصروں اور تفصیلات پر بھی لاگو ہوتا ہے، براہ کرم LLM سے generate کیا گیا مواد copy paste نہ کریں۔ |
||||
|
|
||||
|
### انسانی محنت پر Denial of Service |
||||
|
|
||||
|
خودکار tools اور AI کا استعمال کرکے ایسی PRs یا تبصرے جمع کرنا جنہیں ہمیں احتیاط سے review اور سنبھالنا ہو، ہماری انسانی محنت پر [Denial-of-service attack](https://en.wikipedia.org/wiki/Denial-of-service_attack) کے مترادف ہوگا۔ |
||||
|
|
||||
|
PR جمع کرنے والے شخص کی طرف سے بہت کم محنت (ایک LLM prompt) ہماری طرف سے بڑی مقدار میں محنت (احتیاط سے code کا review) پیدا کرتی ہے۔ |
||||
|
|
||||
|
براہ کرم ایسا نہ کریں۔ |
||||
|
|
||||
|
ہمیں بار بار خودکار PRs یا تبصروں سے spam کرنے والے اکاؤنٹس کو block کرنا ہوگا۔ |
||||
|
|
||||
|
### Tools سمجھداری سے استعمال کریں |
||||
|
|
||||
|
جیسا کہ Uncle Ben نے کہا: |
||||
|
|
||||
|
<blockquote> |
||||
|
بڑی <strike>طاقت</strike> <strong>tools</strong> کے ساتھ بڑی ذمہ داری آتی ہے۔ |
||||
|
</blockquote> |
||||
|
|
||||
|
نادانستہ طور پر نقصان پہنچانے سے بچیں۔ |
||||
|
|
||||
|
آپ کے پاس حیرت انگیز tools ہیں، انہیں سمجھداری سے مؤثر طریقے سے مدد کرنے کے لیے استعمال کریں۔ |
||||
@ -0,0 +1,24 @@ |
|||||
|
# Cloud Providers پر FastAPI Deploy کریں { #deploy-fastapi-on-cloud-providers } |
||||
|
|
||||
|
آپ اپنی FastAPI ایپلیکیشن deploy کرنے کے لیے عملی طور پر **کوئی بھی cloud provider** استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
زیادہ تر معاملات میں، بڑے cloud providers کے پاس FastAPI کو ان کے ساتھ deploy کرنے کی رہنما دستاویزات موجود ہیں۔ |
||||
|
|
||||
|
## FastAPI Cloud { #fastapi-cloud } |
||||
|
|
||||
|
**[FastAPI Cloud](https://fastapicloud.com)** اسی مصنف اور ٹیم نے بنایا ہے جو **FastAPI** کے پیچھے ہے۔ |
||||
|
|
||||
|
یہ کم سے کم محنت کے ساتھ API **بنانے**، **deploy کرنے**، اور **رسائی حاصل کرنے** کے عمل کو آسان بناتا ہے۔ |
||||
|
|
||||
|
یہ FastAPI کے ساتھ apps بنانے کا وہی **developer experience** cloud پر **deploy** کرنے میں لاتا ہے۔ 🎉 |
||||
|
|
||||
|
FastAPI Cloud *FastAPI اور دوستوں* کے اوپن سورس منصوبوں کا بنیادی کفیل اور فنڈنگ فراہم کنندہ ہے۔ ✨ |
||||
|
|
||||
|
## Cloud Providers - کفیل { #cloud-providers-sponsors } |
||||
|
|
||||
|
کچھ اور cloud providers ✨ [**FastAPI کی کفالت**](../help-fastapi.md#sponsor-the-author) ✨ بھی کرتے ہیں۔ 🙇 |
||||
|
|
||||
|
آپ ان کی رہنما دستاویزات کی پیروی اور ان کی خدمات آزمانے پر بھی غور کر سکتے ہیں: |
||||
|
|
||||
|
* [Render](https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi) |
||||
|
* [Railway](https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi) |
||||
@ -0,0 +1,321 @@ |
|||||
|
# Deployment کے تصورات { #deployments-concepts } |
||||
|
|
||||
|
**FastAPI** ایپلیکیشن، یا درحقیقت کسی بھی قسم کی web API deploy کرتے وقت، کئی تصورات ہیں جن کی آپ کو فکر ہوتی ہے، اور ان کا استعمال کرتے ہوئے آپ اپنی **ایپلیکیشن deploy کرنے** کا **سب سے موزوں** طریقہ تلاش کر سکتے ہیں۔ |
||||
|
|
||||
|
کچھ اہم تصورات یہ ہیں: |
||||
|
|
||||
|
* سیکیورٹی - HTTPS |
||||
|
* شروع ہونے پر چلنا |
||||
|
* دوبارہ شروع ہونا |
||||
|
* نقل (چلنے والے processes کی تعداد) |
||||
|
* میموری |
||||
|
* شروع ہونے سے پہلے کے مراحل |
||||
|
|
||||
|
ہم دیکھیں گے کہ یہ **deployments** کو کیسے متاثر کرتے ہیں۔ |
||||
|
|
||||
|
آخر میں، حتمی مقصد یہ ہے کہ آپ اپنے **API صارفین کو** ایسے طریقے سے خدمت فراہم کر سکیں جو **محفوظ** ہو، **رکاوٹوں سے بچے**، اور **compute resources** (مثلاً remote servers/virtual machines) کو زیادہ سے زیادہ مؤثر طریقے سے استعمال کرے۔ 🚀 |
||||
|
|
||||
|
میں آپ کو یہاں ان **تصورات** کے بارے میں کچھ اور بتاؤں گا، اور اس سے امید ہے کہ آپ کو وہ **سمجھ** ملے گی جس کی آپ کو بہت مختلف ماحول میں اپنی API deploy کرنے کے فیصلے کے لیے ضرورت ہوگی، حتیٰ کہ ممکنہ طور پر **مستقبل** کے ایسے ماحول میں بھی جو ابھی موجود نہیں ہیں۔ |
||||
|
|
||||
|
ان تصورات پر غور کر کے، آپ اپنی **APIs** کو deploy کرنے کا بہترین طریقہ **جانچنے اور ڈیزائن** کرنے کے قابل ہوں گے۔ |
||||
|
|
||||
|
اگلے ابواب میں، میں آپ کو FastAPI ایپلیکیشنز deploy کرنے کی مزید **عملی ترکیبیں** دوں گا۔ |
||||
|
|
||||
|
لیکن ابھی کے لیے، آئیے ان اہم **تصوراتی خیالات** کو دیکھتے ہیں۔ یہ تصورات کسی بھی دوسری قسم کی web API پر بھی لاگو ہوتے ہیں۔ 💡 |
||||
|
|
||||
|
## سیکیورٹی - HTTPS { #security-https } |
||||
|
|
||||
|
[HTTPS کے بارے میں پچھلے باب](https.md) میں ہم نے سیکھا کہ HTTPS آپ کی API کے لیے کس طرح encryption فراہم کرتا ہے۔ |
||||
|
|
||||
|
ہم نے یہ بھی دیکھا کہ HTTPS عام طور پر آپ کے application server سے **بیرونی** جزو، ایک **TLS Termination Proxy** کے ذریعے فراہم کیا جاتا ہے۔ |
||||
|
|
||||
|
اور **HTTPS certificates کی تجدید** کے ذمہ دار کسی چیز کا ہونا ضروری ہے، یہ وہی جزو ہو سکتا ہے یا کوئی مختلف چیز ہو سکتی ہے۔ |
||||
|
|
||||
|
### HTTPS کے لیے ٹولز کی مثالیں { #example-tools-for-https } |
||||
|
|
||||
|
TLS Termination Proxy کے طور پر آپ جو ٹولز استعمال کر سکتے ہیں ان میں سے کچھ یہ ہیں: |
||||
|
|
||||
|
* Traefik |
||||
|
* خود بخود certificates کی تجدید سنبھالتا ہے ✨ |
||||
|
* Caddy |
||||
|
* خود بخود certificates کی تجدید سنبھالتا ہے ✨ |
||||
|
* Nginx |
||||
|
* certificate کی تجدید کے لیے Certbot جیسے بیرونی جزو کے ساتھ |
||||
|
* HAProxy |
||||
|
* certificate کی تجدید کے لیے Certbot جیسے بیرونی جزو کے ساتھ |
||||
|
* Kubernetes ایک Ingress Controller جیسے Nginx کے ساتھ |
||||
|
* certificate کی تجدید کے لیے cert-manager جیسے بیرونی جزو کے ساتھ |
||||
|
* cloud provider کے ذریعے ان کی خدمات کے حصے کے طور پر اندرونی طور پر سنبھالا جاتا ہے (نیچے پڑھیں 👇) |
||||
|
|
||||
|
ایک اور اختیار یہ ہے کہ آپ ایک **cloud service** استعمال کر سکتے ہیں جو HTTPS ترتیب دینے سمیت زیادہ کام کرے۔ اس میں کچھ پابندیاں ہو سکتی ہیں یا آپ سے زیادہ معاوضہ لیا جا سکتا ہے، وغیرہ۔ لیکن اس صورت میں، آپ کو خود TLS Termination Proxy ترتیب دینے کی ضرورت نہیں ہوگی۔ |
||||
|
|
||||
|
میں آپ کو اگلے ابواب میں کچھ ٹھوس مثالیں دکھاؤں گا۔ |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
پھر غور کرنے والے اگلے تصورات سب آپ کی اصل API چلانے والے پروگرام (مثلاً Uvicorn) کے بارے میں ہیں۔ |
||||
|
|
||||
|
## پروگرام اور Process { #program-and-process } |
||||
|
|
||||
|
ہم چلنے والے "**process**" کے بارے میں بہت بات کریں گے، اس لیے اس بارے میں واضح ہونا مفید ہے کہ اس کا مطلب کیا ہے، اور "**program**" کے لفظ سے کیا فرق ہے۔ |
||||
|
|
||||
|
### پروگرام کیا ہے { #what-is-a-program } |
||||
|
|
||||
|
**پروگرام** کا لفظ عام طور پر بہت سی چیزوں کے لیے استعمال ہوتا ہے: |
||||
|
|
||||
|
* وہ **کوڈ** جو آپ لکھتے ہیں، **Python فائلیں**۔ |
||||
|
* وہ **فائل** جسے آپریٹنگ سسٹم **چلا** سکتا ہے، مثلاً: `python`، `python.exe` یا `uvicorn`۔ |
||||
|
* ایک مخصوص پروگرام جب یہ آپریٹنگ سسٹم پر **چل** رہا ہو، CPU استعمال کر رہا ہو، اور چیزیں میموری میں محفوظ کر رہا ہو۔ اسے **process** بھی کہتے ہیں۔ |
||||
|
|
||||
|
### Process کیا ہے { #what-is-a-process } |
||||
|
|
||||
|
**Process** کا لفظ عام طور پر زیادہ مخصوص انداز میں استعمال ہوتا ہے، صرف اس چیز کا حوالہ دیتے ہوئے جو آپریٹنگ سسٹم میں چل رہی ہے (جیسا کہ اوپر آخری نکتے میں بتایا گیا): |
||||
|
|
||||
|
* ایک مخصوص پروگرام جب یہ آپریٹنگ سسٹم پر **چل** رہا ہو۔ |
||||
|
* یہ فائل کا حوالہ نہیں دیتا، نہ ہی کوڈ کا، یہ **خاص طور پر** اس چیز کا حوالہ دیتا ہے جو آپریٹنگ سسٹم کے ذریعے **چلائی** اور منظم کی جا رہی ہے۔ |
||||
|
* کوئی بھی پروگرام، کوئی بھی کوڈ، **صرف تبھی کچھ کر سکتا ہے** جب یہ **چلایا** جا رہا ہو۔ تو، جب ایک **process چل** رہا ہو۔ |
||||
|
* process کو آپ یا آپریٹنگ سسٹم **ختم** (یا "kill") کر سکتا ہے۔ اس وقت، یہ چلنا/عمل درآمد ہونا بند ہو جاتا ہے، اور یہ **مزید کچھ نہیں کر سکتا**۔ |
||||
|
* آپ کے کمپیوٹر پر چلنے والی ہر ایپلیکیشن کے پیچھے کوئی process ہوتا ہے، ہر چلنے والا پروگرام، ہر ونڈو، وغیرہ۔ اور عام طور پر کمپیوٹر آن ہونے پر **ایک ہی وقت میں** بہت سے processes چل رہے ہوتے ہیں۔ |
||||
|
* **ایک ہی پروگرام** کے **متعدد processes** ایک ہی وقت میں چل سکتے ہیں۔ |
||||
|
|
||||
|
اگر آپ اپنے آپریٹنگ سسٹم میں "task manager" یا "system monitor" (یا اسی طرح کے ٹولز) دیکھیں، تو آپ ان میں سے بہت سے processes چلتے ہوئے دیکھ سکیں گے۔ |
||||
|
|
||||
|
اور، مثال کے طور پر، آپ شاید دیکھیں گے کہ ایک ہی browser پروگرام (Firefox، Chrome، Edge، وغیرہ) کے متعدد processes چل رہے ہیں۔ وہ عام طور پر ہر ٹیب کے لیے ایک process چلاتے ہیں، اس کے علاوہ کچھ اضافی processes بھی۔ |
||||
|
|
||||
|
<img class="shadow" src="/img/deployment/concepts/image01.png"> |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
اب جب ہم **process** اور **program** کی اصطلاحات کے درمیان فرق جان گئے ہیں، تو آئیے deployments کے بارے میں بات جاری رکھیں۔ |
||||
|
|
||||
|
## شروع ہونے پر چلنا { #running-on-startup } |
||||
|
|
||||
|
زیادہ تر معاملات میں، جب آپ web API بناتے ہیں، تو آپ چاہتے ہیں کہ یہ **ہمیشہ چلتی** رہے، بلا رکاوٹ، تاکہ آپ کے صارفین ہمیشہ اس تک رسائی حاصل کر سکیں۔ یہ یقیناً اس صورت میں ہے جب تک کہ آپ کے پاس کوئی خاص وجہ نہ ہو کہ آپ اسے صرف مخصوص حالات میں چلانا چاہتے ہیں، لیکن زیادہ تر وقت آپ چاہتے ہیں کہ یہ مسلسل چلتی رہے اور **دستیاب** ہو۔ |
||||
|
|
||||
|
### Remote Server میں { #in-a-remote-server } |
||||
|
|
||||
|
جب آپ remote server (cloud server، virtual machine وغیرہ) ترتیب دیتے ہیں تو سب سے آسان کام جو آپ کر سکتے ہیں وہ ہے `fastapi run` (جو Uvicorn استعمال کرتا ہے) یا کچھ ایسا ہی دستی طور پر استعمال کرنا، بالکل اسی طرح جیسے آپ مقامی طور پر development کے دوران کرتے ہیں۔ |
||||
|
|
||||
|
اور یہ کام کرے گا اور **development کے دوران** مفید ہوگا۔ |
||||
|
|
||||
|
لیکن اگر server سے آپ کا کنکشن ٹوٹ جائے، تو **چلنے والا process** شاید ختم ہو جائے گا۔ |
||||
|
|
||||
|
اور اگر server دوبارہ شروع ہوتا ہے (مثلاً updates یا cloud provider کی migrations کے بعد) تو آپ کو شاید **اس کا پتا بھی نہیں چلے گا**۔ اور اس وجہ سے، آپ کو یہ بھی معلوم نہیں ہوگا کہ آپ کو process دستی طور پر دوبارہ شروع کرنا ہے۔ تو، آپ کی API بس بند رہے گی۔ 😱 |
||||
|
|
||||
|
### شروع ہونے پر خود بخود چلنا { #run-automatically-on-startup } |
||||
|
|
||||
|
عام طور پر، آپ شاید چاہیں گے کہ server پروگرام (مثلاً Uvicorn) server شروع ہونے پر خود بخود شروع ہو جائے، اور بغیر کسی **انسانی مداخلت** کے، تاکہ آپ کی API کے ساتھ ہمیشہ ایک process چلتا رہے (مثلاً Uvicorn آپ کی FastAPI app چلا رہا ہو)۔ |
||||
|
|
||||
|
### الگ پروگرام { #separate-program } |
||||
|
|
||||
|
اسے حاصل کرنے کے لیے، آپ کے پاس عام طور پر ایک **الگ پروگرام** ہوگا جو اس بات کو یقینی بنائے گا کہ آپ کی ایپلیکیشن شروع ہونے پر چلے۔ اور بہت سے معاملات میں، یہ دوسرے اجزاء یا ایپلیکیشنز بھی چلانے کو یقینی بنائے گا، مثلاً ایک ڈیٹابیس۔ |
||||
|
|
||||
|
### شروع ہونے پر چلانے کے لیے ٹولز کی مثالیں { #example-tools-to-run-at-startup } |
||||
|
|
||||
|
یہ کام کرنے والے کچھ ٹولز کی مثالیں یہ ہیں: |
||||
|
|
||||
|
* Docker |
||||
|
* Kubernetes |
||||
|
* Docker Compose |
||||
|
* Docker in Swarm Mode |
||||
|
* Systemd |
||||
|
* Supervisor |
||||
|
* cloud provider کے ذریعے ان کی خدمات کے حصے کے طور پر اندرونی طور پر سنبھالا جاتا ہے |
||||
|
* دیگر... |
||||
|
|
||||
|
میں آپ کو اگلے ابواب میں مزید ٹھوس مثالیں دوں گا۔ |
||||
|
|
||||
|
## دوبارہ شروع ہونا { #restarts } |
||||
|
|
||||
|
شروع ہونے پر اپنی ایپلیکیشن چلنے کو یقینی بنانے کی طرح، آپ شاید یہ بھی یقینی بنانا چاہیں گے کہ ناکامیوں کے بعد یہ **دوبارہ شروع** ہو جائے۔ |
||||
|
|
||||
|
### ہم سے غلطیاں ہوتی ہیں { #we-make-mistakes } |
||||
|
|
||||
|
ہم، بحیثیت انسان، ہر وقت **غلطیاں** کرتے ہیں۔ سافٹ ویئر میں تقریباً *ہمیشہ* مختلف جگہوں پر **bugs** چھپے ہوتے ہیں۔ 🐛 |
||||
|
|
||||
|
اور ہم بحیثیت developers جب ان bugs تلاش کرتے ہیں اور نئے فیچرز شامل کرتے ہیں تو کوڈ کو بہتر بناتے رہتے ہیں (شاید نئے bugs بھی شامل کرتے ہوئے 😅)۔ |
||||
|
|
||||
|
### چھوٹی خرابیاں خود بخود سنبھالی جاتی ہیں { #small-errors-automatically-handled } |
||||
|
|
||||
|
FastAPI کے ساتھ web APIs بناتے وقت، اگر ہمارے کوڈ میں کوئی خرابی ہو، تو FastAPI عام طور پر اسے اس واحد request تک محدود رکھے گی جس نے خرابی کو متحرک کیا۔ 🛡 |
||||
|
|
||||
|
صارف کو اس request کے لیے **500 Internal Server Error** ملے گی، لیکن ایپلیکیشن مکمل طور پر بند ہونے کے بجائے اگلی requests کے لیے کام کرتی رہے گی۔ |
||||
|
|
||||
|
### بڑی خرابیاں - بند ہو جانا { #bigger-errors-crashes } |
||||
|
|
||||
|
تاہم، ایسے معاملات ہو سکتے ہیں جہاں ہم ایسا کوڈ لکھتے ہیں جو **پوری ایپلیکیشن کو بند کر دیتا ہے** جس سے Uvicorn اور Python بند ہو جاتے ہیں۔ 💥 |
||||
|
|
||||
|
اور پھر بھی، آپ شاید نہیں چاہیں گے کہ ایپلیکیشن اس لیے بند رہے کہ ایک جگہ خرابی تھی، آپ شاید چاہیں گے کہ یہ کم از کم ان *path operations* کے لیے **چلتی رہے** جو خراب نہیں ہیں۔ |
||||
|
|
||||
|
### بند ہونے کے بعد دوبارہ شروع { #restart-after-crash } |
||||
|
|
||||
|
لیکن ان معاملات میں جہاں واقعی بری خرابیاں چلتے ہوئے **process** کو بند کر دیتی ہیں، آپ ایک بیرونی جزو چاہیں گے جو process کو **دوبارہ شروع** کرنے کا ذمہ دار ہو، کم از کم چند بار... |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
...اگرچہ اگر پوری ایپلیکیشن **فوری طور پر بند ہو رہی ہے** تو شاید اسے ہمیشہ کے لیے دوبارہ شروع کرتے رہنا معقول نہیں ہے۔ لیکن ان معاملات میں، آپ کو شاید development کے دوران، یا کم از کم deployment کے فوراً بعد اس کا پتا چل جائے گا۔ |
||||
|
|
||||
|
تو آئیے ان اصل معاملات پر توجہ مرکوز کریں، جہاں یہ **مستقبل میں** کچھ خاص معاملات میں مکمل طور پر بند ہو سکتا ہے، اور اسے دوبارہ شروع کرنا معقول ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
آپ شاید اپنی ایپلیکیشن دوبارہ شروع کرنے کے ذمہ دار کو ایک **بیرونی جزو** کے طور پر رکھنا چاہیں گے، کیونکہ اس وقت، Uvicorn اور Python کے ساتھ وہی ایپلیکیشن پہلے ہی بند ہو چکی ہوتی ہے، تو اسی app کے اسی کوڈ میں کچھ بھی نہیں ہے جو اس کے بارے میں کچھ کر سکے۔ |
||||
|
|
||||
|
### خود بخود دوبارہ شروع کرنے کے لیے ٹولز کی مثالیں { #example-tools-to-restart-automatically } |
||||
|
|
||||
|
زیادہ تر معاملات میں، وہی ٹول جو **پروگرام کو شروع ہونے پر چلانے** کے لیے استعمال ہوتا ہے، خود بخود **دوبارہ شروع** کرنے کو سنبھالنے کے لیے بھی استعمال ہوتا ہے۔ |
||||
|
|
||||
|
مثال کے طور پر، یہ ان کے ذریعے سنبھالا جا سکتا ہے: |
||||
|
|
||||
|
* Docker |
||||
|
* Kubernetes |
||||
|
* Docker Compose |
||||
|
* Docker in Swarm Mode |
||||
|
* Systemd |
||||
|
* Supervisor |
||||
|
* cloud provider کے ذریعے ان کی خدمات کے حصے کے طور پر اندرونی طور پر سنبھالا جاتا ہے |
||||
|
* دیگر... |
||||
|
|
||||
|
## نقل - Processes اور میموری { #replication-processes-and-memory } |
||||
|
|
||||
|
FastAPI ایپلیکیشن کے ساتھ، `fastapi` command جیسے server پروگرام کا استعمال کرتے ہوئے جو Uvicorn چلاتا ہے، اسے ایک بار **ایک process** میں چلانے سے متعدد صارفین کو بیک وقت خدمت فراہم کی جا سکتی ہے۔ |
||||
|
|
||||
|
لیکن بہت سے معاملات میں، آپ ایک ہی وقت میں کئی worker processes چلانا چاہیں گے۔ |
||||
|
|
||||
|
### متعدد Processes - Workers { #multiple-processes-workers } |
||||
|
|
||||
|
اگر آپ کے پاس ایک process سے زیادہ صارفین ہیں (مثلاً اگر virtual machine بہت بڑی نہیں ہے) اور server کے CPU میں **متعدد cores** ہیں، تو آپ ایک ہی وقت میں ایک ہی ایپلیکیشن کے **متعدد processes** چلا سکتے ہیں، اور تمام requests ان میں تقسیم کر سکتے ہیں۔ |
||||
|
|
||||
|
جب آپ ایک ہی API پروگرام کے **متعدد processes** چلاتے ہیں، تو انہیں عام طور پر **workers** کہا جاتا ہے۔ |
||||
|
|
||||
|
### Worker Processes اور Ports { #worker-processes-and-ports } |
||||
|
|
||||
|
[HTTPS کے بارے میں](https.md) دستاویزات سے یاد ہے کہ server میں ایک port اور IP ایڈریس کے مجموعے پر صرف ایک process سن سکتا ہے؟ |
||||
|
|
||||
|
یہ ابھی بھی درست ہے۔ |
||||
|
|
||||
|
تو، ایک ہی وقت میں **متعدد processes** رکھنے کے لیے، ایک **واحد process کا port پر سننا** ضروری ہے جو پھر ہر worker process کو کسی طرح سے مواصلت منتقل کرے۔ |
||||
|
|
||||
|
### فی Process میموری { #memory-per-process } |
||||
|
|
||||
|
اب، جب پروگرام چیزیں میموری میں لوڈ کرتا ہے، مثلاً ایک machine learning ماڈل کسی variable میں، یا کسی بڑی فائل کا مواد کسی variable میں، تو یہ سب server کی **میموری (RAM) کا کچھ حصہ استعمال** کرتا ہے۔ |
||||
|
|
||||
|
اور متعدد processes عام طور پر **کوئی میموری شیئر نہیں کرتے**۔ اس کا مطلب ہے کہ ہر چلنے والے process کی اپنی چیزیں، variables اور میموری ہوتی ہے۔ اور اگر آپ اپنے کوڈ میں بڑی مقدار میں میموری استعمال کر رہے ہیں، تو **ہر process** اتنی ہی میموری استعمال کرے گا۔ |
||||
|
|
||||
|
### Server کی میموری { #server-memory } |
||||
|
|
||||
|
مثال کے طور پر، اگر آپ کا کوڈ **1 GB سائز** کا Machine Learning ماڈل لوڈ کرتا ہے، جب آپ اپنی API کے ساتھ ایک process چلاتے ہیں، تو یہ کم از کم 1 GB RAM استعمال کرے گا۔ اور اگر آپ **4 processes** (4 workers) شروع کرتے ہیں، تو ہر ایک 1 GB RAM استعمال کرے گا۔ تو مجموعی طور پر، آپ کی API **4 GB RAM** استعمال کرے گی۔ |
||||
|
|
||||
|
اور اگر آپ کے remote server یا virtual machine میں صرف 3 GB RAM ہے، تو 4 GB سے زیادہ RAM لوڈ کرنے کی کوشش مسائل پیدا کرے گی۔ 🚨 |
||||
|
|
||||
|
### متعدد Processes - ایک مثال { #multiple-processes-an-example } |
||||
|
|
||||
|
اس مثال میں، ایک **Manager Process** ہے جو دو **Worker Processes** کو شروع اور کنٹرول کرتا ہے۔ |
||||
|
|
||||
|
یہ Manager Process شاید وہ ہوگا جو IP میں **port** پر سن رہا ہو۔ اور یہ تمام مواصلت worker processes کو منتقل کرے گا۔ |
||||
|
|
||||
|
وہ worker processes وہ ہوں گے جو آپ کی ایپلیکیشن چلا رہے ہوں گے، وہ **request** وصول کرنے اور **response** واپس کرنے کے لیے اصل حسابات انجام دیں گے، اور وہ آپ کی variables میں ڈالی گئی کوئی بھی چیز RAM میں لوڈ کریں گے۔ |
||||
|
|
||||
|
<img src="/img/deployment/concepts/process-ram.drawio.svg"> |
||||
|
|
||||
|
اور یقیناً، اسی مشین پر آپ کی ایپلیکیشن کے علاوہ شاید **دوسرے processes** بھی چل رہے ہوں گے۔ |
||||
|
|
||||
|
ایک دلچسپ بات یہ ہے کہ ہر process کی **CPU استعمال** کی فیصد وقت کے ساتھ **بہت زیادہ تبدیل** ہو سکتی ہے، لیکن **میموری (RAM)** عام طور پر کم و بیش **مستحکم** رہتی ہے۔ |
||||
|
|
||||
|
اگر آپ کے پاس ایسی API ہے جو ہر بار تقریباً یکساں مقدار میں حسابات کرتی ہے اور آپ کے بہت سے صارفین ہیں، تو **CPU کا استعمال** شاید *بھی مستحکم* ہوگا (مسلسل اوپر نیچے جانے کے بجائے)۔ |
||||
|
|
||||
|
### نقل کے ٹولز اور حکمت عملیوں کی مثالیں { #examples-of-replication-tools-and-strategies } |
||||
|
|
||||
|
اسے حاصل کرنے کے کئی طریقے ہو سکتے ہیں، اور میں آپ کو اگلے ابواب میں مخصوص حکمت عملیوں کے بارے میں مزید بتاؤں گا، مثلاً Docker اور containers کے بارے میں بات کرتے وقت۔ |
||||
|
|
||||
|
غور کرنے کی بنیادی پابندی یہ ہے کہ **عوامی IP** میں **port** سنبھالنے والا ایک **واحد** جزو ہونا ضروری ہے۔ اور پھر اس کے پاس نقل شدہ **processes/workers** کو مواصلت **منتقل** کرنے کا کوئی طریقہ ہونا ضروری ہے۔ |
||||
|
|
||||
|
یہاں کچھ ممکنہ مجموعے اور حکمت عملیاں ہیں: |
||||
|
|
||||
|
* **Uvicorn** `--workers` کے ساتھ |
||||
|
* ایک Uvicorn **process manager** **IP** اور **port** پر سنے گا، اور یہ **متعدد Uvicorn worker processes** شروع کرے گا۔ |
||||
|
* **Kubernetes** اور دوسرے تقسیم شدہ **container systems** |
||||
|
* **Kubernetes** پرت میں کوئی چیز **IP** اور **port** پر سنے گی۔ نقل **متعدد containers** رکھ کر ہوگی، ہر ایک میں **ایک Uvicorn process** چل رہا ہوگا۔ |
||||
|
* **Cloud services** جو یہ آپ کے لیے سنبھالتی ہیں |
||||
|
* cloud service شاید **آپ کے لیے نقل سنبھالے گی**۔ یہ ممکنہ طور پر آپ کو **چلانے کے لیے ایک process** یا استعمال کرنے کے لیے ایک **container image** تعین کرنے دے گی، کسی بھی صورت میں، یہ شاید **ایک واحد Uvicorn process** ہوگا، اور cloud service اس کی نقل کی ذمہ دار ہوگی۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
اگر **containers**، Docker، یا Kubernetes کے بارے میں ان میں سے کچھ آئٹمز ابھی زیادہ واضح نہیں ہیں تو فکر نہ کریں۔ |
||||
|
|
||||
|
میں آپ کو container images، Docker، Kubernetes وغیرہ کے بارے میں ایک آئندہ باب میں مزید بتاؤں گا: [FastAPI in Containers - Docker](docker.md)۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## شروع ہونے سے پہلے کے مراحل { #previous-steps-before-starting } |
||||
|
|
||||
|
بہت سے معاملات ہیں جہاں آپ اپنی ایپلیکیشن **شروع ہونے سے پہلے** کچھ مراحل انجام دینا چاہتے ہیں۔ |
||||
|
|
||||
|
مثال کے طور پر، آپ شاید **database migrations** چلانا چاہیں۔ |
||||
|
|
||||
|
لیکن زیادہ تر معاملات میں، آپ یہ مراحل صرف **ایک بار** انجام دینا چاہیں گے۔ |
||||
|
|
||||
|
تو، ایپلیکیشن شروع کرنے سے پہلے ان **پچھلے مراحل** کو انجام دینے کے لیے آپ ایک **واحد process** رکھنا چاہیں گے۔ |
||||
|
|
||||
|
اور آپ کو اس بات کو یقینی بنانا ہوگا کہ یہ واحد process ان پچھلے مراحل کو چلائے *چاہے* بعد میں آپ خود ایپلیکیشن کے لیے **متعدد processes** (متعدد workers) شروع کریں۔ اگر یہ مراحل **متعدد processes** کے ذریعے چلائے جائیں، تو وہ **متوازی** طور پر چلا کر کام کی **نقل** کریں گے، اور اگر مراحل کوئی نازک چیز ہوں جیسے database migration، تو وہ ایک دوسرے سے ٹکراؤ پیدا کر سکتے ہیں۔ |
||||
|
|
||||
|
یقیناً، کچھ معاملات ایسے ہیں جہاں پچھلے مراحل کو کئی بار چلانے میں کوئی مسئلہ نہیں ہے، اس صورت میں اسے سنبھالنا بہت آسان ہے۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
اس بات کو بھی ذہن میں رکھیں کہ آپ کے سیٹ اپ پر منحصر ہے، کچھ معاملات میں آپ کو اپنی ایپلیکیشن شروع کرنے سے پہلے **کسی پچھلے مرحلے کی ضرورت ہی نہ ہو**۔ |
||||
|
|
||||
|
اس صورت میں، آپ کو اس میں سے کسی کے بارے میں فکر کرنے کی ضرورت نہیں ہوگی۔ 🤷 |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### پچھلے مراحل کی حکمت عملیوں کی مثالیں { #examples-of-previous-steps-strategies } |
||||
|
|
||||
|
یہ بہت زیادہ اس بات پر **منحصر** ہوگا کہ آپ **اپنا سسٹم کیسے deploy** کرتے ہیں، اور یہ شاید پروگرامز شروع کرنے، دوبارہ شروع کرنے وغیرہ کے طریقے سے جڑا ہوگا۔ |
||||
|
|
||||
|
یہاں کچھ ممکنہ خیالات ہیں: |
||||
|
|
||||
|
* Kubernetes میں "Init Container" جو آپ کے app container سے پہلے چلے |
||||
|
* ایک bash script جو پچھلے مراحل چلائے اور پھر آپ کی ایپلیکیشن شروع کرے |
||||
|
* آپ کو پھر بھی *اس* bash script کو شروع/دوبارہ شروع کرنے، خرابیوں کا پتا لگانے وغیرہ کا طریقہ درکار ہوگا۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
میں آپ کو containers کے ساتھ ایسا کرنے کی مزید ٹھوس مثالیں ایک آئندہ باب میں دوں گا: [FastAPI in Containers - Docker](docker.md)۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## وسائل کا استعمال { #resource-utilization } |
||||
|
|
||||
|
آپ کا/کے server(s) ایک **وسیلہ** ہے/ہیں، آپ اپنے پروگراموں سے استعمال کر سکتے ہیں، CPUs پر حساب کا وقت، اور دستیاب RAM میموری۔ |
||||
|
|
||||
|
آپ سسٹم کے کتنے وسائل استعمال کرنا چاہتے ہیں؟ یہ سوچنا آسان ہو سکتا ہے "زیادہ نہیں"، لیکن حقیقت میں، آپ شاید **بند ہوئے بغیر زیادہ سے زیادہ** استعمال کرنا چاہیں گے۔ |
||||
|
|
||||
|
اگر آپ 3 servers کے لیے ادائیگی کر رہے ہیں لیکن ان کی RAM اور CPU کا صرف تھوڑا سا استعمال کر رہے ہیں، تو آپ شاید **پیسے ضائع کر رہے ہیں** 💸، اور شاید **server کی بجلی بھی ضائع کر رہے ہیں** 🌎، وغیرہ۔ |
||||
|
|
||||
|
اس صورت میں، صرف 2 servers رکھنا اور ان کے وسائل (CPU، میموری، ڈسک، نیٹ ورک bandwidth وغیرہ) کا زیادہ فیصد استعمال کرنا بہتر ہو سکتا ہے۔ |
||||
|
|
||||
|
دوسری طرف، اگر آپ کے پاس 2 servers ہیں اور آپ ان کی **CPU اور RAM کا 100%** استعمال کر رہے ہیں، تو کسی وقت ایک process مزید میموری مانگے گا، اور server کو ڈسک کو "میموری" کے طور پر استعمال کرنا پڑے گا (جو ہزاروں گنا سست ہو سکتا ہے)، یا حتیٰ کہ **بند ہو سکتا ہے**۔ یا ایک process کو کچھ حساب کرنے کی ضرورت ہوگی اور اسے CPU دوبارہ خالی ہونے تک انتظار کرنا پڑے گا۔ |
||||
|
|
||||
|
اس صورت میں، **ایک اضافی server** لینا اور اس پر کچھ processes چلانا بہتر ہوگا تاکہ سب کے پاس **کافی RAM اور CPU وقت** ہو۔ |
||||
|
|
||||
|
یہ بھی ممکن ہے کہ کسی وجہ سے آپ کی API کے استعمال میں **اچانک اضافہ** ہو جائے۔ شاید یہ وائرل ہو گئی، یا شاید کچھ دوسری خدمات یا bots اسے استعمال کرنا شروع کر دیں۔ اور آپ ان حالات میں محفوظ رہنے کے لیے اضافی وسائل رکھنا چاہ سکتے ہیں۔ |
||||
|
|
||||
|
آپ ہدف کے لیے ایک **من مانی تعداد** مقرر کر سکتے ہیں، مثلاً وسائل کے استعمال کے **50% سے 90% کے درمیان** کچھ۔ بات یہ ہے کہ شاید یہ وہ اصل چیزیں ہیں جو آپ ناپنا اور اپنے deployments کو بہتر بنانے کے لیے استعمال کرنا چاہیں گے۔ |
||||
|
|
||||
|
آپ اپنے server میں CPU اور RAM کا استعمال یا ہر process کے ذریعے استعمال ہونے والی مقدار دیکھنے کے لیے `htop` جیسے آسان ٹولز استعمال کر سکتے ہیں۔ یا آپ زیادہ پیچیدہ مانیٹرنگ ٹولز استعمال کر سکتے ہیں، جو servers پر تقسیم شدہ ہو سکتے ہیں، وغیرہ۔ |
||||
|
|
||||
|
## خلاصہ { #recap } |
||||
|
|
||||
|
آپ نے یہاں ان اصل تصورات میں سے کچھ پڑھے ہیں جو آپ کو اپنی ایپلیکیشن deploy کرنے کا فیصلہ کرتے وقت ذہن میں رکھنے کی ضرورت ہوگی: |
||||
|
|
||||
|
* سیکیورٹی - HTTPS |
||||
|
* شروع ہونے پر چلنا |
||||
|
* دوبارہ شروع ہونا |
||||
|
* نقل (چلنے والے processes کی تعداد) |
||||
|
* میموری |
||||
|
* شروع ہونے سے پہلے کے مراحل |
||||
|
|
||||
|
ان خیالات کو سمجھنا اور انہیں لاگو کرنے کا طریقہ جاننا آپ کو deployments کو ترتیب اور بہتر بنانے کے فیصلے کرنے کے لیے ضروری سمجھ فراہم کرے۔ 🤓 |
||||
|
|
||||
|
اگلے حصوں میں، میں آپ کو ممکنہ حکمت عملیوں کی مزید ٹھوس مثالیں دوں گا۔ 🚀 |
||||
@ -0,0 +1,618 @@ |
|||||
|
# FastAPI in Containers - Docker { #fastapi-in-containers-docker } |
||||
|
|
||||
|
FastAPI ایپلیکیشنز deploy کرتے وقت ایک عام طریقہ **Linux container image** بنانا ہے۔ یہ عام طور پر [**Docker**](https://www.docker.com/) استعمال کرتے ہوئے کیا جاتا ہے۔ پھر آپ اس container image کو کئی ممکنہ طریقوں سے deploy کر سکتے ہیں۔ |
||||
|
|
||||
|
Linux containers استعمال کرنے کے کئی فوائد ہیں بشمول **سیکیورٹی**، **نقل پذیری**، **سادگی**، اور دیگر۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
جلدی میں ہیں اور یہ سب پہلے سے جانتے ہیں؟ نیچے [`Dockerfile` 👇](#build-a-docker-image-for-fastapi) پر جائیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
<details> |
||||
|
<summary>Dockerfile Preview 👀</summary> |
||||
|
|
||||
|
```Dockerfile |
||||
|
FROM python:3.14 |
||||
|
|
||||
|
WORKDIR /code |
||||
|
|
||||
|
COPY ./requirements.txt /code/requirements.txt |
||||
|
|
||||
|
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt |
||||
|
|
||||
|
COPY ./app /code/app |
||||
|
|
||||
|
CMD ["fastapi", "run", "app/main.py", "--port", "80"] |
||||
|
|
||||
|
# If running behind a proxy like Nginx or Traefik add --proxy-headers |
||||
|
# CMD ["fastapi", "run", "app/main.py", "--port", "80", "--proxy-headers"] |
||||
|
``` |
||||
|
|
||||
|
</details> |
||||
|
|
||||
|
## Container کیا ہے { #what-is-a-container } |
||||
|
|
||||
|
Containers (بنیادی طور پر Linux containers) ایپلیکیشنز کو ان کی تمام dependencies اور ضروری فائلوں سمیت پیکیج کرنے کا ایک بہت **ہلکا** طریقہ ہے جبکہ انہیں اسی سسٹم میں دوسرے containers (دوسری ایپلیکیشنز یا اجزاء) سے الگ رکھتے ہیں۔ |
||||
|
|
||||
|
Linux containers host (مشین، virtual machine، cloud server وغیرہ) کے اسی Linux kernel کا استعمال کرتے ہوئے چلتے ہیں۔ اس کا مطلب ہے کہ وہ بہت ہلکے ہیں (مکمل virtual machines جو پورا آپریٹنگ سسٹم ایمولیٹ کرتی ہیں ان کے مقابلے میں)۔ |
||||
|
|
||||
|
اس طرح، containers **کم وسائل** استعمال کرتے ہیں، processes کو براہ راست چلانے کے مقابلے میں تقریباً اتنی ہی مقدار (virtual machine بہت زیادہ استعمال کرے گی)۔ |
||||
|
|
||||
|
Containers کے اپنے **الگ** چلنے والے processes (عام طور پر صرف ایک process)، فائل سسٹم، اور نیٹ ورک بھی ہوتے ہیں، جو deployment، سیکیورٹی، development وغیرہ کو آسان بناتے ہیں۔ |
||||
|
|
||||
|
## Container Image کیا ہے { #what-is-a-container-image } |
||||
|
|
||||
|
ایک **container** ایک **container image** سے چلایا جاتا ہے۔ |
||||
|
|
||||
|
Container image تمام فائلوں، environment variables، اور ڈیفالٹ command/پروگرام کا ایک **جامد** ورژن ہے جو container میں موجود ہونا چاہیے۔ **جامد** کا مطلب ہے کہ container **image** نہیں چل رہی، عمل درآمد نہیں ہو رہا، یہ صرف پیکیج شدہ فائلیں اور metadata ہے۔ |
||||
|
|
||||
|
"**container image**" جو محفوظ جامد مواد ہے اس کے برعکس، "**container**" عام طور پر چلنے والے instance، اس چیز کا حوالہ دیتا ہے جو **عمل درآمد** ہو رہی ہے۔ |
||||
|
|
||||
|
جب **container** شروع ہوتا ہے اور چل رہا ہوتا ہے (**container image** سے شروع ہوا) تو یہ فائلیں، environment variables وغیرہ بنا یا تبدیل کر سکتا ہے۔ وہ تبدیلیاں صرف اس container میں موجود ہوں گی، لیکن بنیادی container image میں برقرار نہیں رہیں گی (ڈسک پر محفوظ نہیں ہوں گی)۔ |
||||
|
|
||||
|
Container image **پروگرام** فائل اور مواد سے موازنہ کی جا سکتی ہے، مثلاً `python` اور کوئی فائل `main.py`۔ |
||||
|
|
||||
|
اور **container** خود (**container image** کے برعکس) image کا اصل چلنے والا instance ہے، ایک **process** سے موازنہ کیا جا سکتا ہے۔ درحقیقت، ایک container صرف تبھی چل رہا ہوتا ہے جب اس کا **process چل** رہا ہو (اور عام طور پر یہ صرف ایک واحد process ہوتا ہے)۔ جب اس میں کوئی process نہ چل رہا ہو تو container رک جاتا ہے۔ |
||||
|
|
||||
|
## Container Images { #container-images } |
||||
|
|
||||
|
Docker **container images** اور **containers** بنانے اور منظم کرنے کے اہم ٹولز میں سے ایک رہا ہے۔ |
||||
|
|
||||
|
اور ایک عوامی [Docker Hub](https://hub.docker.com/) ہے جس میں بہت سے ٹولز، ماحول، ڈیٹابیسز اور ایپلیکیشنز کے لیے پہلے سے بنی **سرکاری container images** ہیں۔ |
||||
|
|
||||
|
مثال کے طور پر، ایک سرکاری [Python Image](https://hub.docker.com/_/python) ہے۔ |
||||
|
|
||||
|
اور ڈیٹابیسز جیسی مختلف چیزوں کے لیے بہت سی اور images ہیں، مثلاً: |
||||
|
|
||||
|
* [PostgreSQL](https://hub.docker.com/_/postgres) |
||||
|
* [MySQL](https://hub.docker.com/_/mysql) |
||||
|
* [MongoDB](https://hub.docker.com/_/mongo) |
||||
|
* [Redis](https://hub.docker.com/_/redis) وغیرہ۔ |
||||
|
|
||||
|
پہلے سے بنی container image استعمال کرنے سے مختلف ٹولز کو **ملانا** اور استعمال کرنا بہت آسان ہے۔ مثال کے طور پر، نیا ڈیٹابیس آزمانے کے لیے۔ زیادہ تر معاملات میں، آپ **سرکاری images** استعمال کر سکتے ہیں، اور بس environment variables سے انہیں ترتیب دے سکتے ہیں۔ |
||||
|
|
||||
|
اس طرح، بہت سے معاملات میں آپ containers اور Docker کے بارے میں سیکھ سکتے ہیں اور اس علم کو بہت سے مختلف ٹولز اور اجزاء کے ساتھ دوبارہ استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
تو، آپ مختلف چیزوں کے ساتھ **متعدد containers** چلائیں گے، جیسے ڈیٹابیس، Python ایپلیکیشن، React frontend ایپلیکیشن والا web server، اور انہیں ان کے اندرونی نیٹ ورک کے ذریعے جوڑیں گے۔ |
||||
|
|
||||
|
تمام container management systems (جیسے Docker یا Kubernetes) میں یہ نیٹ ورکنگ خصوصیات شامل ہوتی ہیں۔ |
||||
|
|
||||
|
## Containers اور Processes { #containers-and-processes } |
||||
|
|
||||
|
ایک **container image** عام طور پر اپنے metadata میں ڈیفالٹ پروگرام یا command شامل کرتی ہے جو **container** شروع ہونے پر چلنی چاہیے اور اس پروگرام کو دیے جانے والے parameters۔ بالکل اسی طرح جیسے command line میں ہوتا۔ |
||||
|
|
||||
|
جب **container** شروع ہوتا ہے، تو یہ وہ command/پروگرام چلائے گا (اگرچہ آپ اسے override کر کے مختلف command/پروگرام چلا سکتے ہیں)۔ |
||||
|
|
||||
|
Container تب تک چل رہا ہوتا ہے جب تک **مرکزی process** (command یا پروگرام) چل رہا ہو۔ |
||||
|
|
||||
|
Container میں عام طور پر ایک **واحد process** ہوتا ہے، لیکن مرکزی process سے subprocesses شروع کرنا بھی ممکن ہے، اور اس طرح آپ کے پاس ایک ہی container میں **متعدد processes** ہوں گے۔ |
||||
|
|
||||
|
لیکن **کم از کم ایک چلنے والے process** کے بغیر چلنے والا container ممکن نہیں ہے۔ اگر مرکزی process رک جائے، تو container رک جاتا ہے۔ |
||||
|
|
||||
|
## FastAPI کے لیے Docker Image بنائیں { #build-a-docker-image-for-fastapi } |
||||
|
|
||||
|
ٹھیک ہے، آئیے اب کچھ بناتے ہیں! 🚀 |
||||
|
|
||||
|
میں آپ کو دکھاؤں گا کہ **سرکاری Python** image کی بنیاد پر، FastAPI کے لیے **شروع سے Docker image** کیسے بنائیں۔ |
||||
|
|
||||
|
یہی وہ ہے جو آپ **زیادہ تر معاملات** میں کرنا چاہیں گے، مثلاً: |
||||
|
|
||||
|
* **Kubernetes** یا اسی طرح کے ٹولز استعمال کرتے ہوئے |
||||
|
* **Raspberry Pi** پر چلاتے ہوئے |
||||
|
* کسی cloud service استعمال کرتے ہوئے جو آپ کے لیے container image چلائے، وغیرہ۔ |
||||
|
|
||||
|
### Package Requirements { #package-requirements } |
||||
|
|
||||
|
آپ کے پاس عام طور پر اپنی ایپلیکیشن کے لیے **package requirements** کسی فائل میں ہوں گی۔ |
||||
|
|
||||
|
یہ بنیادی طور پر اس ٹول پر منحصر ہوگا جو آپ ان requirements کو **انسٹال** کرنے کے لیے استعمال کرتے ہیں۔ |
||||
|
|
||||
|
سب سے عام طریقہ `requirements.txt` فائل رکھنا ہے جس میں package کے نام اور ان کے ورژن، ہر لائن میں ایک، ہوتے ہیں۔ |
||||
|
|
||||
|
آپ یقیناً ورژنز کی حدود مقرر کرنے کے لیے وہی خیالات استعمال کریں گے جو آپ نے [FastAPI ورژنز کے بارے میں](versions.md) میں پڑھے۔ |
||||
|
|
||||
|
مثال کے طور پر، آپ کی `requirements.txt` کچھ ایسی نظر آ سکتی ہے: |
||||
|
|
||||
|
``` |
||||
|
fastapi[standard]>=0.113.0,<0.114.0 |
||||
|
pydantic>=2.7.0,<3.0.0 |
||||
|
``` |
||||
|
|
||||
|
اور آپ عام طور پر ان package dependencies کو `pip` سے انسٹال کریں گے، مثلاً: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ pip install -r requirements.txt |
||||
|
---> 100% |
||||
|
Successfully installed fastapi pydantic |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
package dependencies تعین اور انسٹال کرنے کے لیے دوسرے فارمیٹس اور ٹولز بھی ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### **FastAPI** کوڈ بنائیں { #create-the-fastapi-code } |
||||
|
|
||||
|
* ایک `app` ڈائریکٹری بنائیں اور اس میں داخل ہوں۔ |
||||
|
* ایک خالی `__init__.py` فائل بنائیں۔ |
||||
|
* ایک `main.py` فائل بنائیں اس کے ساتھ: |
||||
|
|
||||
|
```Python |
||||
|
from fastapi import FastAPI |
||||
|
|
||||
|
app = FastAPI() |
||||
|
|
||||
|
|
||||
|
@app.get("/") |
||||
|
def read_root(): |
||||
|
return {"Hello": "World"} |
||||
|
|
||||
|
|
||||
|
@app.get("/items/{item_id}") |
||||
|
def read_item(item_id: int, q: str | None = None): |
||||
|
return {"item_id": item_id, "q": q} |
||||
|
``` |
||||
|
|
||||
|
### Dockerfile { #dockerfile } |
||||
|
|
||||
|
اب اسی پراجیکٹ ڈائریکٹری میں ایک `Dockerfile` فائل بنائیں اس کے ساتھ: |
||||
|
|
||||
|
```{ .dockerfile .annotate } |
||||
|
# (1)! |
||||
|
FROM python:3.14 |
||||
|
|
||||
|
# (2)! |
||||
|
WORKDIR /code |
||||
|
|
||||
|
# (3)! |
||||
|
COPY ./requirements.txt /code/requirements.txt |
||||
|
|
||||
|
# (4)! |
||||
|
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt |
||||
|
|
||||
|
# (5)! |
||||
|
COPY ./app /code/app |
||||
|
|
||||
|
# (6)! |
||||
|
CMD ["fastapi", "run", "app/main.py", "--port", "80"] |
||||
|
``` |
||||
|
|
||||
|
1. سرکاری Python base image سے شروع کریں۔ |
||||
|
|
||||
|
2. موجودہ ورکنگ ڈائریکٹری `/code` مقرر کریں۔ |
||||
|
|
||||
|
یہاں ہم `requirements.txt` فائل اور `app` ڈائریکٹری رکھیں گے۔ |
||||
|
|
||||
|
3. requirements والی فائل کو `/code` ڈائریکٹری میں کاپی کریں۔ |
||||
|
|
||||
|
**صرف** requirements والی فائل پہلے کاپی کریں، باقی کوڈ نہیں۔ |
||||
|
|
||||
|
چونکہ یہ فائل **اکثر تبدیل نہیں ہوتی**، Docker اسے پہچان لے گا اور اس مرحلے کے لیے **cache** استعمال کرے گا، اگلے مرحلے کے لیے بھی cache فعال رکھتے ہوئے۔ |
||||
|
|
||||
|
4. requirements فائل میں موجود package dependencies انسٹال کریں۔ |
||||
|
|
||||
|
`--no-cache-dir` اختیار `pip` کو بتاتا ہے کہ ڈاؤن لوڈ شدہ packages مقامی طور پر محفوظ نہ کرے، کیونکہ یہ صرف تبھی ہوتا جب `pip` انہی packages کو دوبارہ انسٹال کرنے کے لیے چلایا جاتا، لیکن containers کے ساتھ کام کرتے وقت ایسا نہیں ہوتا۔ |
||||
|
|
||||
|
/// note | نوٹ |
||||
|
|
||||
|
`--no-cache-dir` صرف `pip` سے متعلق ہے، اس کا Docker یا containers سے کوئی تعلق نہیں ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
`--upgrade` اختیار `pip` کو بتاتا ہے کہ اگر packages پہلے سے انسٹال ہیں تو انہیں اپ گریڈ کرے۔ |
||||
|
|
||||
|
چونکہ فائل کاپی کرنے کا پچھلا مرحلہ **Docker cache** کے ذریعے پہچانا جا سکتا ہے، یہ مرحلہ بھی دستیاب ہونے پر **Docker cache استعمال کرے** گا۔ |
||||
|
|
||||
|
اس مرحلے میں cache استعمال کرنے سے development کے دوران بار بار image بناتے وقت آپ کا بہت سا **وقت بچے** گا، ہر بار تمام dependencies **ڈاؤن لوڈ اور انسٹال** کرنے کے بجائے۔ |
||||
|
|
||||
|
5. `./app` ڈائریکٹری کو `/code` ڈائریکٹری کے اندر کاپی کریں۔ |
||||
|
|
||||
|
چونکہ اس میں وہ تمام کوڈ ہے جو **سب سے زیادہ تبدیل ہوتا ہے** Docker **cache** آسانی سے اس یا اس کے بعد کے **مراحل** کے لیے استعمال نہیں ہو سکے گا۔ |
||||
|
|
||||
|
اس لیے، container image کے build time کو بہتر بنانے کے لیے اسے `Dockerfile` کے **آخر کے قریب** رکھنا ضروری ہے۔ |
||||
|
|
||||
|
6. `fastapi run` استعمال کرنے کے لیے **command** مقرر کریں، جو نیچے Uvicorn استعمال کرتا ہے۔ |
||||
|
|
||||
|
`CMD` strings کی ایک فہرست لیتا ہے، ان میں سے ہر string وہ ہے جو آپ command line میں spaces سے الگ کر کے ٹائپ کرتے۔ |
||||
|
|
||||
|
یہ command **موجودہ ورکنگ ڈائریکٹری** سے چلایا جائے گا، وہی `/code` ڈائریکٹری جو آپ نے اوپر `WORKDIR /code` سے مقرر کی۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
کوڈ میں ہر نمبر والے بلبلے پر کلک کر کے دیکھیں کہ ہر لائن کیا کرتی ہے۔ 👆 |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
/// warning | انتباہ |
||||
|
|
||||
|
ہمیشہ `CMD` ہدایت کی **exec form** استعمال کرنا یقینی بنائیں، جیسا کہ نیچے بیان کیا گیا ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
#### `CMD` - Exec Form استعمال کریں { #use-cmd-exec-form } |
||||
|
|
||||
|
[`CMD`](https://docs.docker.com/reference/dockerfile/#cmd) Docker ہدایت دو شکلوں میں لکھی جا سکتی ہے: |
||||
|
|
||||
|
✅ **Exec** form: |
||||
|
|
||||
|
```Dockerfile |
||||
|
# ✅ Do this |
||||
|
CMD ["fastapi", "run", "app/main.py", "--port", "80"] |
||||
|
``` |
||||
|
|
||||
|
⛔️ **Shell** form: |
||||
|
|
||||
|
```Dockerfile |
||||
|
# ⛔️ Don't do this |
||||
|
CMD fastapi run app/main.py --port 80 |
||||
|
``` |
||||
|
|
||||
|
ہمیشہ **exec** form استعمال کرنا یقینی بنائیں تاکہ FastAPI خوبصورتی سے shutdown ہو سکے اور [lifespan events](../advanced/events.md) فعال ہوں۔ |
||||
|
|
||||
|
آپ اس کے بارے میں مزید [Docker docs for shell and exec form](https://docs.docker.com/reference/dockerfile/#shell-and-exec-form) میں پڑھ سکتے ہیں۔ |
||||
|
|
||||
|
`docker compose` استعمال کرتے وقت یہ کافی نمایاں ہو سکتا ہے۔ مزید تکنیکی تفصیلات کے لیے Docker Compose FAQ کا یہ حصہ دیکھیں: [Why do my services take 10 seconds to recreate or stop?](https://docs.docker.com/compose/faq/#why-do-my-services-take-10-seconds-to-recreate-or-stop)۔ |
||||
|
|
||||
|
#### ڈائریکٹری کا ڈھانچہ { #directory-structure } |
||||
|
|
||||
|
اب آپ کے پاس ایسا ڈائریکٹری ڈھانچہ ہونا چاہیے: |
||||
|
|
||||
|
``` |
||||
|
. |
||||
|
├── app |
||||
|
│ ├── __init__.py |
||||
|
│ └── main.py |
||||
|
├── Dockerfile |
||||
|
└── requirements.txt |
||||
|
``` |
||||
|
|
||||
|
#### TLS Termination Proxy کے پیچھے { #behind-a-tls-termination-proxy } |
||||
|
|
||||
|
اگر آپ اپنا container TLS Termination Proxy (load balancer) جیسے Nginx یا Traefik کے پیچھے چلا رہے ہیں، تو `--proxy-headers` اختیار شامل کریں، یہ Uvicorn کو (FastAPI CLI کے ذریعے) بتائے گا کہ اس proxy کی طرف سے بھیجے گئے headers پر اعتماد کرے جو بتاتے ہیں کہ ایپلیکیشن HTTPS وغیرہ کے پیچھے چل رہی ہے۔ |
||||
|
|
||||
|
```Dockerfile |
||||
|
CMD ["fastapi", "run", "app/main.py", "--proxy-headers", "--port", "80"] |
||||
|
``` |
||||
|
|
||||
|
#### Docker Cache { #docker-cache } |
||||
|
|
||||
|
اس `Dockerfile` میں ایک اہم چال ہے، ہم پہلے **صرف dependencies والی فائل** کاپی کرتے ہیں، باقی کوڈ نہیں۔ آئیے بتاتے ہیں کہ ایسا کیوں ہے۔ |
||||
|
|
||||
|
```Dockerfile |
||||
|
COPY ./requirements.txt /code/requirements.txt |
||||
|
``` |
||||
|
|
||||
|
Docker اور دوسرے ٹولز ان container images کو **بتدریج** بناتے ہیں، `Dockerfile` کے اوپر سے شروع کرتے ہوئے اور `Dockerfile` کی ہر ہدایت سے بنائی گئی فائلوں کو شامل کرتے ہوئے **ایک پرت دوسری کے اوپر** رکھتے ہیں۔ |
||||
|
|
||||
|
Docker اور اسی طرح کے ٹولز image بناتے وقت **اندرونی cache** بھی استعمال کرتے ہیں، اگر کوئی فائل آخری بار container image بنانے کے بعد سے تبدیل نہیں ہوئی، تو یہ فائل کو دوبارہ کاپی کرنے اور شروع سے نئی پرت بنانے کے بجائے آخری بار بنائی گئی **وہی پرت دوبارہ استعمال** کرے گا۔ |
||||
|
|
||||
|
صرف فائلوں کی کاپی سے بچنا ضروری نہیں کہ چیزوں کو بہت بہتر بنائے، لیکن چونکہ اس نے اس مرحلے کے لیے cache استعمال کیا، یہ **اگلے مرحلے کے لیے cache استعمال** کر سکتا ہے۔ مثلاً، یہ dependencies انسٹال کرنے والی ہدایت کے لیے cache استعمال کر سکتا ہے: |
||||
|
|
||||
|
```Dockerfile |
||||
|
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt |
||||
|
``` |
||||
|
|
||||
|
Package requirements والی فائل **اکثر تبدیل نہیں ہوتی**۔ تو، صرف وہ فائل کاپی کرنے سے، Docker اس مرحلے کے لیے **cache استعمال** کر سکے گا۔ |
||||
|
|
||||
|
اور پھر، Docker اگلے مرحلے کے لیے بھی **cache استعمال** کر سکے گا جو ان dependencies کو ڈاؤن لوڈ اور انسٹال کرتا ہے۔ اور یہیں ہم **بہت سا وقت بچاتے** ہیں۔ ✨ ...اور اکتاہٹ سے بچتے ہیں۔ 😪😆 |
||||
|
|
||||
|
Package dependencies ڈاؤن لوڈ اور انسٹال کرنے میں **منٹ** لگ سکتے ہیں، لیکن **cache** استعمال کرنے میں زیادہ سے زیادہ **سیکنڈ** لگیں گے۔ |
||||
|
|
||||
|
اور چونکہ آپ development کے دوران بار بار container image بناتے رہیں گے تاکہ آپ کے کوڈ کی تبدیلیاں کام کر رہی ہیں، اس سے بہت زیادہ مجموعی وقت بچتا ہے۔ |
||||
|
|
||||
|
پھر، `Dockerfile` کے آخر کے قریب، ہم تمام کوڈ کاپی کرتے ہیں۔ چونکہ یہ وہ ہے جو **سب سے زیادہ تبدیل ہوتا ہے**، ہم اسے آخر کے قریب رکھتے ہیں، کیونکہ تقریباً ہمیشہ، اس مرحلے کے بعد کی کوئی بھی چیز cache استعمال نہیں کر سکے گی۔ |
||||
|
|
||||
|
```Dockerfile |
||||
|
COPY ./app /code/app |
||||
|
``` |
||||
|
|
||||
|
### Docker Image بنائیں { #build-the-docker-image } |
||||
|
|
||||
|
اب جب تمام فائلیں جگہ پر ہیں، آئیے container image بناتے ہیں۔ |
||||
|
|
||||
|
* پراجیکٹ ڈائریکٹری میں جائیں (جہاں آپ کی `Dockerfile` ہے، آپ کی `app` ڈائریکٹری پر مشتمل)۔ |
||||
|
* اپنی FastAPI image بنائیں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ docker build -t myimage . |
||||
|
|
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
آخر میں `.` پر دھیان دیں، یہ `./` کے مساوی ہے، یہ Docker کو بتاتا ہے کہ container image بنانے کے لیے کون سی ڈائریکٹری استعمال کرنی ہے۔ |
||||
|
|
||||
|
اس معاملے میں، یہ وہی موجودہ ڈائریکٹری (`.`) ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### Docker Container شروع کریں { #start-the-docker-container } |
||||
|
|
||||
|
* اپنی image کی بنیاد پر container چلائیں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ docker run -d --name mycontainer -p 80:80 myimage |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
## اسے چیک کریں { #check-it } |
||||
|
|
||||
|
آپ اسے اپنے Docker container کے URL میں چیک کر سکتے ہیں، مثلاً: [http://192.168.99.100/items/5?q=somequery](http://192.168.99.100/items/5?q=somequery) یا [http://127.0.0.1/items/5?q=somequery](http://127.0.0.1/items/5?q=somequery) (یا مساوی، آپ کے Docker host کا استعمال کرتے ہوئے)۔ |
||||
|
|
||||
|
آپ کو کچھ ایسا نظر آئے گا: |
||||
|
|
||||
|
```JSON |
||||
|
{"item_id": 5, "q": "somequery"} |
||||
|
``` |
||||
|
|
||||
|
## انٹرایکٹو API دستاویزات { #interactive-api-docs } |
||||
|
|
||||
|
اب آپ [http://192.168.99.100/docs](http://192.168.99.100/docs) یا [http://127.0.0.1/docs](http://127.0.0.1/docs) (یا مساوی، آپ کے Docker host کا استعمال کرتے ہوئے) پر جا سکتے ہیں۔ |
||||
|
|
||||
|
آپ کو خودکار انٹرایکٹو API دستاویزات نظر آئیں گی ([Swagger UI](https://github.com/swagger-api/swagger-ui) کی فراہم کردہ): |
||||
|
|
||||
|
 |
||||
|
|
||||
|
## متبادل API دستاویزات { #alternative-api-docs } |
||||
|
|
||||
|
اور آپ [http://192.168.99.100/redoc](http://192.168.99.100/redoc) یا [http://127.0.0.1/redoc](http://127.0.0.1/redoc) (یا مساوی، آپ کے Docker host کا استعمال کرتے ہوئے) پر بھی جا سکتے ہیں۔ |
||||
|
|
||||
|
آپ کو متبادل خودکار دستاویزات نظر آئیں گی ([ReDoc](https://github.com/Rebilly/ReDoc) کی فراہم کردہ): |
||||
|
|
||||
|
 |
||||
|
|
||||
|
## واحد فائل FastAPI کے ساتھ Docker Image بنائیں { #build-a-docker-image-with-a-single-file-fastapi } |
||||
|
|
||||
|
اگر آپ کی FastAPI واحد فائل ہے، مثلاً `./app` ڈائریکٹری کے بغیر `main.py`، تو آپ کا فائل ڈھانچہ کچھ ایسا ہو سکتا ہے: |
||||
|
|
||||
|
``` |
||||
|
. |
||||
|
├── Dockerfile |
||||
|
├── main.py |
||||
|
└── requirements.txt |
||||
|
``` |
||||
|
|
||||
|
پھر آپ کو بس `Dockerfile` کے اندر فائل کاپی کرنے کے متعلقہ راستے تبدیل کرنے ہوں گے: |
||||
|
|
||||
|
```{ .dockerfile .annotate hl_lines="10 13" } |
||||
|
FROM python:3.14 |
||||
|
|
||||
|
WORKDIR /code |
||||
|
|
||||
|
COPY ./requirements.txt /code/requirements.txt |
||||
|
|
||||
|
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt |
||||
|
|
||||
|
# (1)! |
||||
|
COPY ./main.py /code/ |
||||
|
|
||||
|
# (2)! |
||||
|
CMD ["fastapi", "run", "main.py", "--port", "80"] |
||||
|
``` |
||||
|
|
||||
|
1. `main.py` فائل کو `/code` ڈائریکٹری میں براہ راست کاپی کریں (بغیر `./app` ڈائریکٹری کے)۔ |
||||
|
|
||||
|
2. اپنی واحد فائل `main.py` میں ایپلیکیشن چلانے کے لیے `fastapi run` استعمال کریں۔ |
||||
|
|
||||
|
جب آپ `fastapi run` کو فائل دیتے ہیں تو یہ خود بخود پتا لگا لے گا کہ یہ واحد فائل ہے نہ کہ کسی package کا حصہ اور جانے گا کہ اسے کیسے import کرنا ہے اور آپ کی FastAPI app کو خدمت فراہم کرنی ہے۔ 😎 |
||||
|
|
||||
|
## Deployment کے تصورات { #deployment-concepts } |
||||
|
|
||||
|
آئیے containers کے حوالے سے انہی [Deployment تصورات](concepts.md) کے بارے میں دوبارہ بات کرتے ہیں۔ |
||||
|
|
||||
|
Containers بنیادی طور پر ایپلیکیشن **بنانے اور deploy کرنے** کے عمل کو آسان بنانے کا ایک ٹول ہیں، لیکن یہ ان **deployment تصورات** کو سنبھالنے کا کوئی خاص طریقہ نافذ نہیں کرتے، اور کئی ممکنہ حکمت عملیاں ہیں۔ |
||||
|
|
||||
|
**اچھی خبر** یہ ہے کہ ہر مختلف حکمت عملی کے ساتھ تمام deployment تصورات کا احاطہ کرنے کا ایک طریقہ موجود ہے۔ 🎉 |
||||
|
|
||||
|
آئیے containers کے حوالے سے ان **deployment تصورات** کا جائزہ لیتے ہیں: |
||||
|
|
||||
|
* HTTPS |
||||
|
* شروع ہونے پر چلنا |
||||
|
* دوبارہ شروع ہونا |
||||
|
* نقل (چلنے والے processes کی تعداد) |
||||
|
* میموری |
||||
|
* شروع ہونے سے پہلے کے مراحل |
||||
|
|
||||
|
## HTTPS { #https } |
||||
|
|
||||
|
اگر ہم صرف FastAPI ایپلیکیشن کے لیے **container image** (اور بعد میں چلنے والے **container**) پر توجہ مرکوز کریں، تو HTTPS عام طور پر ایک اور ٹول کے ذریعے **بیرونی طور پر** سنبھالا جائے گا۔ |
||||
|
|
||||
|
یہ ایک اور container ہو سکتا ہے، مثلاً [Traefik](https://traefik.io/) کے ساتھ، **HTTPS** اور **certificates** کے **خودکار** حصول کو سنبھالتے ہوئے۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
Traefik کے Docker، Kubernetes اور دوسروں کے ساتھ integrations ہیں، تو اس کے ساتھ اپنے containers کے لیے HTTPS ترتیب دینا بہت آسان ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
متبادل کے طور پر، HTTPS ایک cloud provider کے ذریعے ان کی خدمات میں سے ایک کے طور پر سنبھالا جا سکتا ہے (جبکہ ابھی بھی ایپلیکیشن container میں چل رہی ہو)۔ |
||||
|
|
||||
|
## شروع ہونے پر چلنا اور دوبارہ شروع ہونا { #running-on-startup-and-restarts } |
||||
|
|
||||
|
عام طور پر آپ کے container کو **شروع اور چلانے** کا ذمہ دار ایک اور ٹول ہوتا ہے۔ |
||||
|
|
||||
|
یہ **Docker** براہ راست ہو سکتا ہے، **Docker Compose**، **Kubernetes**، کوئی **cloud service** وغیرہ۔ |
||||
|
|
||||
|
زیادہ تر (یا تمام) معاملات میں، شروع ہونے پر container چلانے اور ناکامیوں پر دوبارہ شروع کرنے کو فعال کرنے کا ایک آسان اختیار ہوتا ہے۔ مثلاً Docker میں، یہ command line اختیار `--restart` ہے۔ |
||||
|
|
||||
|
بغیر containers کے، ایپلیکیشنز کو شروع ہونے پر چلانا اور دوبارہ شروع کرنا مشکل اور پیچیدہ ہو سکتا ہے۔ لیکن جب **containers کے ساتھ** کام کر رہے ہوں تو زیادہ تر معاملات میں یہ فعالیت بطور ڈیفالٹ شامل ہوتی ہے۔ ✨ |
||||
|
|
||||
|
## نقل - Processes کی تعداد { #replication-number-of-processes } |
||||
|
|
||||
|
اگر آپ کے پاس **Kubernetes**، Docker Swarm Mode، Nomad، یا متعدد مشینوں پر تقسیم شدہ containers منظم کرنے کے لیے کوئی اور ملتا جلتا پیچیدہ نظام والی مشینوں کا <dfn title="A group of machines that are configured to be connected and work together in some way.">cluster</dfn> ہے، تو آپ شاید ہر container میں **process manager** (جیسے Uvicorn with workers) استعمال کرنے کے بجائے **cluster کی سطح** پر **نقل سنبھالنا** چاہیں گے۔ |
||||
|
|
||||
|
ان تقسیم شدہ container management systems جیسے Kubernetes میں عام طور پر آنے والی requests کے لیے **load balancing** کی حمایت کرتے ہوئے **containers کی نقل** سنبھالنے کا کوئی مربوط طریقہ ہوتا ہے۔ سب **cluster کی سطح** پر۔ |
||||
|
|
||||
|
ان معاملات میں، آپ شاید [اوپر بیان کیے گئے طریقے](#dockerfile) سے **شروع سے Docker image** بنانا چاہیں گے، اپنی dependencies انسٹال کرتے ہوئے، اور متعدد Uvicorn workers استعمال کرنے کے بجائے **ایک واحد Uvicorn process** چلاتے ہوئے۔ |
||||
|
|
||||
|
### Load Balancer { #load-balancer } |
||||
|
|
||||
|
Containers استعمال کرتے وقت، عام طور پر کوئی جزو **مرکزی port پر سن** رہا ہوتا ہے۔ یہ ممکنہ طور پر ایک اور container ہو سکتا ہے جو **HTTPS** سنبھالنے کے لیے **TLS Termination Proxy** بھی ہو یا کوئی ملتا جلتا ٹول۔ |
||||
|
|
||||
|
چونکہ یہ جزو requests کا **بوجھ** لیتا ہے اور اسے workers میں (امید ہے) **متوازن** طریقے سے تقسیم کرتا ہے، اسے عام طور پر **Load Balancer** بھی کہا جاتا ہے۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
HTTPS کے لیے استعمال ہونے والا وہی **TLS Termination Proxy** جزو شاید **Load Balancer** بھی ہوگا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
اور containers کے ساتھ کام کرتے وقت، وہی نظام جو آپ انہیں شروع اور منظم کرنے کے لیے استعمال کرتے ہیں اس میں پہلے سے اندرونی ٹولز ہوں گے جو **نیٹ ورک مواصلت** (مثلاً HTTP requests) اس **load balancer** (جو **TLS Termination Proxy** بھی ہو سکتا ہے) سے آپ کی app والے container(s) تک منتقل کریں۔ |
||||
|
|
||||
|
### ایک Load Balancer - متعدد Worker Containers { #one-load-balancer-multiple-worker-containers } |
||||
|
|
||||
|
**Kubernetes** یا اسی طرح کے تقسیم شدہ container management systems کے ساتھ کام کرتے وقت، ان کے اندرونی نیٹ ورکنگ میکانزم کا استعمال واحد **load balancer** کو جو مرکزی **port** پر سن رہا ہے، مواصلت (requests) ممکنہ طور پر آپ کی app چلانے والے **متعدد containers** تک منتقل کرنے کی اجازت دے گا۔ |
||||
|
|
||||
|
آپ کی app چلانے والے ان میں سے ہر container میں عام طور پر **صرف ایک process** ہوگا (مثلاً آپ کی FastAPI ایپلیکیشن چلانے والا Uvicorn process)۔ وہ سب **ایک جیسے containers** ہوں گے، وہی چیز چلا رہے ہوں گے، لیکن ہر ایک اپنے process، میموری وغیرہ کے ساتھ۔ اس طرح آپ CPU کے **مختلف cores** میں، یا حتیٰ کہ **مختلف مشینوں** میں **متوازی عمل** سے فائدہ اٹھائیں گے۔ |
||||
|
|
||||
|
اور **load balancer** والا تقسیم شدہ container system آپ کی app والے ہر container کو **باری باری** requests **تقسیم کرے** گا۔ تو، ہر request آپ کی app چلانے والے متعدد **نقل شدہ containers** میں سے ایک کے ذریعے سنبھالی جا سکتی ہے۔ |
||||
|
|
||||
|
اور عام طور پر یہ **load balancer** آپ کے cluster میں *دوسری* apps (مثلاً مختلف domain، یا مختلف URL path prefix کے تحت) کی طرف جانے والی requests بھی سنبھال سکے گا، اور وہ مواصلت آپ کے cluster میں چلنے والی *اس دوسری* ایپلیکیشن کے صحیح containers تک منتقل کرے گا۔ |
||||
|
|
||||
|
### فی Container ایک Process { #one-process-per-container } |
||||
|
|
||||
|
اس قسم کے منظرنامے میں، آپ شاید **فی container ایک واحد (Uvicorn) process** رکھنا چاہیں گے، کیونکہ آپ پہلے ہی cluster کی سطح پر نقل سنبھال رہے ہوں گے۔ |
||||
|
|
||||
|
تو، اس صورت میں، آپ container میں متعدد workers **نہیں** رکھنا چاہیں گے، مثلاً `--workers` command line اختیار کے ساتھ۔ آپ فی container صرف ایک **واحد Uvicorn process** رکھنا چاہیں گے (لیکن شاید متعدد containers)۔ |
||||
|
|
||||
|
Container کے اندر ایک اور process manager رکھنا (جیسا کہ متعدد workers کے ساتھ ہوگا) صرف **غیر ضروری پیچیدگی** شامل کرے گا جو آپ شاید پہلے ہی اپنے cluster system سے سنبھال رہے ہیں۔ |
||||
|
|
||||
|
### متعدد Processes والے Containers اور خصوصی صورتیں { #containers-with-multiple-processes-and-special-cases } |
||||
|
|
||||
|
یقیناً، ایسی **خصوصی صورتیں** ہیں جہاں آپ ایک **container** میں اندر کئی **Uvicorn worker processes** رکھنا چاہ سکتے ہیں۔ |
||||
|
|
||||
|
ان معاملات میں، آپ workers کی تعداد مقرر کرنے کے لیے `--workers` command line اختیار استعمال کر سکتے ہیں: |
||||
|
|
||||
|
```{ .dockerfile .annotate } |
||||
|
FROM python:3.14 |
||||
|
|
||||
|
WORKDIR /code |
||||
|
|
||||
|
COPY ./requirements.txt /code/requirements.txt |
||||
|
|
||||
|
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt |
||||
|
|
||||
|
COPY ./app /code/app |
||||
|
|
||||
|
# (1)! |
||||
|
CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"] |
||||
|
``` |
||||
|
|
||||
|
1. یہاں ہم workers کی تعداد 4 مقرر کرنے کے لیے `--workers` command line اختیار استعمال کرتے ہیں۔ |
||||
|
|
||||
|
یہاں کچھ مثالیں ہیں کہ یہ کب معنی خیز ہو سکتا ہے: |
||||
|
|
||||
|
#### ایک سادہ App { #a-simple-app } |
||||
|
|
||||
|
اگر آپ کی ایپلیکیشن **اتنی سادہ** ہے کہ اسے **ایک واحد server** پر چلایا جا سکتا ہے، cluster نہیں، تو آپ container میں process manager رکھنا چاہ سکتے ہیں۔ |
||||
|
|
||||
|
#### Docker Compose { #docker-compose } |
||||
|
|
||||
|
آپ **Docker Compose** کے ساتھ **ایک واحد server** (cluster نہیں) پر deploy کر رہے ہو سکتے ہیں، تو آپ کے پاس مشترکہ نیٹ ورک اور **load balancing** کو برقرار رکھتے ہوئے containers کی نقل منظم کرنے کا آسان طریقہ نہ ہو (Docker Compose کے ساتھ)۔ |
||||
|
|
||||
|
تب آپ **ایک واحد container** میں **process manager** کے ساتھ اندر **کئی worker processes** شروع کرنا چاہ سکتے ہیں۔ |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
اصل بات یہ ہے کہ ان میں سے **کوئی بھی** ایسے **پتھر پر لکھے قوانین** نہیں ہیں جن کی آپ کو آنکھیں بند کر کے پیروی کرنی ہے۔ آپ ان خیالات کو **اپنے استعمال کے معاملے کا جائزہ لینے** اور اپنے نظام کے لیے بہترین طریقہ فیصلہ کرنے کے لیے استعمال کر سکتے ہیں، یہ دیکھتے ہوئے کہ ان تصورات کو کیسے منظم کریں: |
||||
|
|
||||
|
* سیکیورٹی - HTTPS |
||||
|
* شروع ہونے پر چلنا |
||||
|
* دوبارہ شروع ہونا |
||||
|
* نقل (چلنے والے processes کی تعداد) |
||||
|
* میموری |
||||
|
* شروع ہونے سے پہلے کے مراحل |
||||
|
|
||||
|
## میموری { #memory } |
||||
|
|
||||
|
اگر آپ **فی container ایک واحد process** چلاتے ہیں تو ان میں سے ہر container (اگر نقل شدہ ہیں تو ایک سے زیادہ) کے ذریعے استعمال ہونے والی میموری کم و بیش واضح، مستحکم اور محدود ہوگی۔ |
||||
|
|
||||
|
اور پھر آپ اپنے container management system (مثلاً **Kubernetes** میں) کی ترتیبات میں وہی میموری کی حدود اور ضروریات مقرر کر سکتے ہیں۔ اس طرح یہ ان کی ضرورت کی میموری کی مقدار اور cluster کی مشینوں میں دستیاب مقدار کو مدنظر رکھتے ہوئے **دستیاب مشینوں** میں **containers کی نقل** کر سکے گا۔ |
||||
|
|
||||
|
اگر آپ کی ایپلیکیشن **سادہ** ہے، تو یہ شاید **مسئلہ نہیں** ہوگا، اور آپ کو سخت میموری کی حدود مقرر کرنے کی ضرورت نہیں ہوگی۔ لیکن اگر آپ **بہت زیادہ میموری استعمال** کر رہے ہیں (مثلاً **machine learning** ماڈلز کے ساتھ)، تو آپ کو چیک کرنا چاہیے کہ آپ کتنی میموری استعمال کر رہے ہیں اور **ہر مشین** میں چلنے والے **containers کی تعداد** کو ایڈجسٹ کرنا چاہیے (اور شاید اپنے cluster میں مزید مشینیں شامل کریں)۔ |
||||
|
|
||||
|
اگر آپ **فی container متعدد processes** چلاتے ہیں تو آپ کو یقینی بنانا ہوگا کہ شروع ہونے والے processes کی تعداد دستیاب سے **زیادہ میموری استعمال** نہ کرے۔ |
||||
|
|
||||
|
## شروع ہونے سے پہلے کے مراحل اور Containers { #previous-steps-before-starting-and-containers } |
||||
|
|
||||
|
اگر آپ containers (مثلاً Docker، Kubernetes) استعمال کر رہے ہیں تو دو اصل طریقے ہیں جو آپ استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
### متعدد Containers { #multiple-containers } |
||||
|
|
||||
|
اگر آپ کے پاس **متعدد containers** ہیں، شاید ہر ایک **واحد process** چلا رہا ہے (مثلاً **Kubernetes** cluster میں)، تو آپ شاید نقل شدہ worker containers چلانے **سے پہلے** ایک **الگ container** میں **پچھلے مراحل** کا کام ایک واحد container میں، ایک واحد process چلاتے ہوئے کرنا چاہیں گے۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
اگر آپ Kubernetes استعمال کر رہے ہیں، تو یہ شاید ایک [Init Container](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/) ہوگا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
اگر آپ کے استعمال کے معاملے میں ان پچھلے مراحل کو **متعدد بار متوازی طور پر** چلانے میں کوئی مسئلہ نہیں ہے (مثلاً اگر آپ database migrations نہیں چلا رہے، بلکہ صرف چیک کر رہے ہیں کہ ڈیٹابیس تیار ہے یا نہیں)، تو آپ انہیں مرکزی process شروع کرنے سے پہلے ہر container میں بھی رکھ سکتے ہیں۔ |
||||
|
|
||||
|
### واحد Container { #single-container } |
||||
|
|
||||
|
اگر آپ کے پاس سادہ سیٹ اپ ہے، **واحد container** کے ساتھ جو پھر متعدد **worker processes** شروع کرتا ہے (یا صرف ایک process بھی)، تو آپ ان پچھلے مراحل کو اسی container میں، app کے ساتھ process شروع کرنے سے پہلے چلا سکتے ہیں۔ |
||||
|
|
||||
|
### بنیادی Docker Image { #base-docker-image } |
||||
|
|
||||
|
پہلے ایک سرکاری FastAPI Docker image ہوا کرتی تھی: [tiangolo/uvicorn-gunicorn-fastapi](https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker)۔ لیکن اب یہ متروک ہے۔ ⛔️ |
||||
|
|
||||
|
آپ کو شاید یہ بنیادی Docker image (یا کوئی اور ایسی ہی) استعمال **نہیں** کرنی چاہیے۔ |
||||
|
|
||||
|
اگر آپ **Kubernetes** (یا دوسرے) استعمال کر رہے ہیں اور پہلے سے متعدد **containers** کے ساتھ cluster کی سطح پر **نقل** ترتیب دے رہے ہیں۔ ان معاملات میں، آپ اوپر بیان کیے گئے طریقے سے **شروع سے image بنانا** بہتر ہے: [FastAPI کے لیے Docker Image بنائیں](#build-a-docker-image-for-fastapi)۔ |
||||
|
|
||||
|
اور اگر آپ کو متعدد workers کی ضرورت ہے تو آپ آسانی سے `--workers` command line اختیار استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
Docker image اس وقت بنائی گئی تھی جب Uvicorn مردہ workers کو منظم اور دوبارہ شروع کرنے کی حمایت نہیں کرتا تھا، تو Gunicorn کو Uvicorn کے ساتھ استعمال کرنا ضروری تھا، جس نے کافی پیچیدگی شامل کی، صرف اس لیے کہ Gunicorn Uvicorn worker processes کو منظم اور دوبارہ شروع کر سکے۔ |
||||
|
|
||||
|
لیکن اب جب Uvicorn (اور `fastapi` command) `--workers` استعمال کرنے کی حمایت کرتا ہے، اپنی خود کی بنانے کے بجائے بنیادی Docker image استعمال کرنے کی کوئی وجہ نہیں ہے (یہ تقریباً اتنا ہی کوڈ ہے 😅)۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Container Image Deploy کریں { #deploy-the-container-image } |
||||
|
|
||||
|
Container (Docker) Image ہونے کے بعد اسے deploy کرنے کے کئی طریقے ہیں۔ |
||||
|
|
||||
|
مثال کے طور پر: |
||||
|
|
||||
|
* واحد server پر **Docker Compose** کے ساتھ |
||||
|
* **Kubernetes** cluster کے ساتھ |
||||
|
* Docker Swarm Mode cluster کے ساتھ |
||||
|
* Nomad جیسے دوسرے ٹول کے ساتھ |
||||
|
* cloud service کے ساتھ جو آپ کی container image لے کر deploy کرے |
||||
|
|
||||
|
## `uv` کے ساتھ Docker Image { #docker-image-with-uv } |
||||
|
|
||||
|
اگر آپ اپنا پراجیکٹ انسٹال اور منظم کرنے کے لیے [uv](https://github.com/astral-sh/uv) استعمال کر رہے ہیں، تو آپ ان کی [uv Docker guide](https://docs.astral.sh/uv/guides/integration/docker/) کی پیروی کر سکتے ہیں۔ |
||||
|
|
||||
|
## خلاصہ { #recap } |
||||
|
|
||||
|
Container systems (مثلاً **Docker** اور **Kubernetes** کے ساتھ) استعمال کرنا تمام **deployment تصورات** کو سنبھالنا کافی سیدھا بنا دیتا ہے: |
||||
|
|
||||
|
* HTTPS |
||||
|
* شروع ہونے پر چلنا |
||||
|
* دوبارہ شروع ہونا |
||||
|
* نقل (چلنے والے processes کی تعداد) |
||||
|
* میموری |
||||
|
* شروع ہونے سے پہلے کے مراحل |
||||
|
|
||||
|
زیادہ تر معاملات میں، آپ شاید کوئی بنیادی image استعمال نہیں کرنا چاہیں گے، بلکہ سرکاری Python Docker image کی بنیاد پر **شروع سے container image بنائیں** گے۔ |
||||
|
|
||||
|
`Dockerfile` میں ہدایات کی **ترتیب** اور **Docker cache** کا خیال رکھ کر آپ اپنی پیداواریت بڑھانے (اور اکتاہٹ سے بچنے) کے لیے **build time کم** کر سکتے ہیں۔ 😎 |
||||
@ -0,0 +1,65 @@ |
|||||
|
# FastAPI Cloud { #fastapi-cloud } |
||||
|
|
||||
|
آپ اپنی FastAPI app کو [FastAPI Cloud](https://fastapicloud.com) پر **ایک command** سے deploy کر سکتے ہیں، اگر آپ نے ابھی تک نہیں کیا تو ویٹنگ لسٹ میں شامل ہو جائیں۔ 🚀 |
||||
|
|
||||
|
## Login { #login } |
||||
|
|
||||
|
یقینی بنائیں کہ آپ کے پاس پہلے سے **FastAPI Cloud** اکاؤنٹ ہے (ہم نے آپ کو ویٹنگ لسٹ سے دعوت دی ہے 😉)۔ |
||||
|
|
||||
|
پھر لاگ ان کریں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ fastapi login |
||||
|
|
||||
|
You are logged in to FastAPI Cloud 🚀 |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
## Deploy { #deploy } |
||||
|
|
||||
|
اب اپنی app deploy کریں، **ایک command** سے: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ fastapi deploy |
||||
|
|
||||
|
Deploying to FastAPI Cloud... |
||||
|
|
||||
|
✅ Deployment successful! |
||||
|
|
||||
|
🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
بس! اب آپ اس URL پر اپنی app تک رسائی حاصل کر سکتے ہیں۔ ✨ |
||||
|
|
||||
|
## FastAPI Cloud کے بارے میں { #about-fastapi-cloud } |
||||
|
|
||||
|
**[FastAPI Cloud](https://fastapicloud.com)** اسی مصنف اور ٹیم نے بنایا ہے جو **FastAPI** کے پیچھے ہے۔ |
||||
|
|
||||
|
یہ کم سے کم محنت کے ساتھ API **بنانے**، **deploy کرنے**، اور **رسائی حاصل کرنے** کے عمل کو آسان بناتا ہے۔ |
||||
|
|
||||
|
یہ FastAPI کے ساتھ apps بنانے کا وہی **developer experience** cloud پر **deploy** کرنے میں لاتا ہے۔ 🎉 |
||||
|
|
||||
|
یہ ان زیادہ تر چیزوں کا بھی خیال رکھے گا جن کی آپ کو app deploy کرتے وقت ضرورت ہوتی ہے، جیسے: |
||||
|
|
||||
|
* HTTPS |
||||
|
* requests کی بنیاد پر autoscaling کے ساتھ نقل |
||||
|
* وغیرہ۔ |
||||
|
|
||||
|
FastAPI Cloud *FastAPI اور دوستوں* کے اوپن سورس منصوبوں کا بنیادی کفیل اور فنڈنگ فراہم کنندہ ہے۔ ✨ |
||||
|
|
||||
|
## دوسرے cloud providers پر deploy کریں { #deploy-to-other-cloud-providers } |
||||
|
|
||||
|
FastAPI اوپن سورس ہے اور معیارات پر مبنی ہے۔ آپ FastAPI apps کو اپنی پسند کے کسی بھی cloud provider پر deploy کر سکتے ہیں۔ |
||||
|
|
||||
|
اپنے cloud provider کی رہنما دستاویزات کی پیروی کریں تاکہ FastAPI apps کو ان کے ساتھ deploy کریں۔ 🤓 |
||||
|
|
||||
|
## اپنا خود کا server deploy کریں { #deploy-your-own-server } |
||||
|
|
||||
|
میں آپ کو بعد میں اس **Deployment** رہنما میں تمام تفصیلات سکھاؤں گا، تاکہ آپ سمجھ سکیں کہ کیا ہو رہا ہے، کیا ہونا چاہیے، یا FastAPI apps کو اپنے طور پر، اپنے servers کے ساتھ بھی کیسے deploy کریں۔ 🤓 |
||||
@ -0,0 +1,231 @@ |
|||||
|
# HTTPS کے بارے میں { #about-https } |
||||
|
|
||||
|
یہ سوچنا آسان ہے کہ HTTPS کوئی ایسی چیز ہے جو بس "فعال" ہوتی ہے یا نہیں ہوتی۔ |
||||
|
|
||||
|
لیکن یہ اس سے کہیں زیادہ پیچیدہ ہے۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
اگر آپ جلدی میں ہیں یا آپ کو پرواہ نہیں ہے، تو مختلف تکنیکوں کے ساتھ سب کچھ ترتیب دینے کی مرحلہ وار ہدایات کے لیے اگلے حصوں میں جائیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
**HTTPS کی بنیادی باتیں** جاننے کے لیے، ایک صارف کے نقطہ نظر سے، دیکھیں [https://howhttps.works/](https://howhttps.works/)۔ |
||||
|
|
||||
|
اب، ایک **developer کے نقطہ نظر** سے، HTTPS کے بارے میں سوچتے وقت ذہن میں رکھنے کی کئی چیزیں ہیں: |
||||
|
|
||||
|
* HTTPS کے لیے، **server** کو ایک **تیسری جماعت** کی طرف سے تیار کردہ **"certificates"** رکھنے کی ضرورت ہے۔ |
||||
|
* وہ certificates دراصل تیسری جماعت سے **حاصل** کیے جاتے ہیں، "تیار" نہیں کیے جاتے۔ |
||||
|
* Certificates کی ایک **مدت** ہوتی ہے۔ |
||||
|
* وہ **ختم** ہو جاتے ہیں۔ |
||||
|
* اور پھر انہیں **تجدید** کرنے، تیسری جماعت سے **دوبارہ حاصل** کرنے کی ضرورت ہوتی ہے۔ |
||||
|
* کنکشن کی encryption **TCP سطح** پر ہوتی ہے۔ |
||||
|
* یہ **HTTP سے نیچے** ایک پرت ہے۔ |
||||
|
* تو، **certificate اور encryption** کی سنبھال **HTTP سے پہلے** ہوتی ہے۔ |
||||
|
* **TCP کو "domains" کے بارے میں معلوم نہیں ہوتا**۔ صرف IP ایڈریسز کے بارے میں۔ |
||||
|
* درخواست کیے گئے **مخصوص domain** کی معلومات **HTTP ڈیٹا** میں جاتی ہے۔ |
||||
|
* **HTTPS certificates** ایک **مخصوص domain** کی **تصدیق** کرتے ہیں، لیکن protocol اور encryption TCP سطح پر ہوتی ہے، یہ **جاننے سے پہلے** کہ کس domain سے معاملہ ہو رہا ہے۔ |
||||
|
* **بطور ڈیفالٹ**، اس کا مطلب یہ ہوگا کہ آپ کے پاس **ہر IP ایڈریس پر صرف ایک HTTPS certificate** ہو سکتا ہے۔ |
||||
|
* اس سے قطع نظر کہ آپ کا server کتنا بڑا ہے یا اس پر موجود ہر ایپلیکیشن کتنی چھوٹی ہے۔ |
||||
|
* تاہم، اس کا ایک **حل** موجود ہے۔ |
||||
|
* **TLS** protocol (جو TCP سطح پر، HTTP سے پہلے encryption سنبھالتا ہے) کی ایک **توسیع** ہے جسے **[<abbr title="Server Name Indication">SNI</abbr>](https://en.wikipedia.org/wiki/Server_Name_Indication)** کہتے ہیں۔ |
||||
|
* یہ SNI توسیع ایک واحد server (ایک **واحد IP ایڈریس** کے ساتھ) کو **کئی HTTPS certificates** رکھنے اور **متعدد HTTPS domains/ایپلیکیشنز** کو خدمت فراہم کرنے کی اجازت دیتی ہے۔ |
||||
|
* اس کے کام کرنے کے لیے، server پر چلنے والے ایک **واحد** جزو (پروگرام) کو، جو **عوامی IP ایڈریس** پر سن رہا ہو، server کے **تمام HTTPS certificates** رکھنے ہوں گے۔ |
||||
|
* محفوظ کنکشن حاصل کرنے **کے بعد**، مواصلاتی protocol **ابھی بھی HTTP** ہے۔ |
||||
|
* مواد **encrypted** ہوتے ہیں، اگرچہ وہ **HTTP protocol** کے ساتھ بھیجے جا رہے ہوتے ہیں۔ |
||||
|
|
||||
|
ایک عام طریقہ یہ ہے کہ server (مشین، host وغیرہ) پر **ایک پروگرام/HTTP server** چلایا جائے جو **تمام HTTPS حصوں کا انتظام** کرے: **encrypted HTTPS requests** وصول کرے، **decrypted HTTP requests** اسی server میں چلنے والی اصل HTTP ایپلیکیشن (اس معاملے میں **FastAPI** ایپلیکیشن) کو بھیجے، ایپلیکیشن سے **HTTP response** لے، مناسب **HTTPS certificate** استعمال کرتے ہوئے اسے **encrypt** کرے اور **HTTPS** استعمال کرتے ہوئے واپس صارف کو بھیجے۔ اس server کو اکثر **[TLS Termination Proxy](https://en.wikipedia.org/wiki/TLS_termination_proxy)** کہا جاتا ہے۔ |
||||
|
|
||||
|
TLS Termination Proxy کے طور پر آپ جو اختیارات استعمال کر سکتے ہیں ان میں سے کچھ یہ ہیں: |
||||
|
|
||||
|
* Traefik (جو certificate کی تجدید بھی سنبھال سکتا ہے) |
||||
|
* Caddy (جو certificate کی تجدید بھی سنبھال سکتا ہے) |
||||
|
* Nginx |
||||
|
* HAProxy |
||||
|
|
||||
|
## Let's Encrypt { #lets-encrypt } |
||||
|
|
||||
|
Let's Encrypt سے پہلے، یہ **HTTPS certificates** قابل اعتماد تیسری جماعتوں کی طرف سے فروخت کیے جاتے تھے۔ |
||||
|
|
||||
|
ان میں سے ایک certificate حاصل کرنے کا عمل مشکل ہوتا تھا، کافی کاغذی کارروائی درکار ہوتی تھی اور certificates کافی مہنگے ہوتے تھے۔ |
||||
|
|
||||
|
لیکن پھر **[Let's Encrypt](https://letsencrypt.org/)** بنایا گیا۔ |
||||
|
|
||||
|
یہ Linux Foundation کا ایک منصوبہ ہے۔ یہ خود بخود طریقے سے **مفت HTTPS certificates** فراہم کرتا ہے۔ یہ certificates تمام معیاری خفیہ سیکیورٹی استعمال کرتے ہیں، اور مختصر مدتی (تقریباً 3 ماہ) ہوتے ہیں، تو اپنی کم مدت کی وجہ سے **سیکیورٹی دراصل بہتر** ہے۔ |
||||
|
|
||||
|
Domains محفوظ طریقے سے تصدیق شدہ ہوتے ہیں اور certificates خود بخود تیار ہوتے ہیں۔ اس سے ان certificates کی تجدید کو بھی خودکار بنانے کی اجازت ملتی ہے۔ |
||||
|
|
||||
|
خیال یہ ہے کہ ان certificates کے حصول اور تجدید کو خودکار بنایا جائے تاکہ آپ **محفوظ HTTPS، مفت، ہمیشہ کے لیے** حاصل کر سکیں۔ |
||||
|
|
||||
|
## Developers کے لیے HTTPS { #https-for-developers } |
||||
|
|
||||
|
یہاں ایک مثال ہے کہ ایک HTTPS API کیسی نظر آ سکتی ہے، مرحلہ وار، بنیادی طور پر developers کے لیے اہم خیالات پر توجہ دیتے ہوئے۔ |
||||
|
|
||||
|
### Domain Name { #domain-name } |
||||
|
|
||||
|
یہ سب شاید آپ کے کوئی **domain name حاصل** کرنے سے شروع ہوگا۔ پھر، آپ اسے DNS server میں ترتیب دیں گے (ممکنہ طور پر آپ کا وہی cloud provider)۔ |
||||
|
|
||||
|
آپ کو شاید ایک cloud server (virtual machine) یا کچھ ایسا ہی ملے گا، اور اس کا ایک <dfn title="Doesn't change over time. Not dynamic.">مقررہ</dfn> **عوامی IP ایڈریس** ہوگا۔ |
||||
|
|
||||
|
DNS server(s) میں آپ ایک ریکارڈ (ایک "`A record`") ترتیب دیں گے تاکہ **آپ کا domain** آپ کے **server کے عوامی IP ایڈریس** کی طرف اشارہ کرے۔ |
||||
|
|
||||
|
آپ شاید یہ صرف ایک بار کریں گے، پہلی بار، جب سب کچھ ترتیب دے رہے ہوں۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
یہ Domain Name کا حصہ HTTPS سے بہت پہلے ہے، لیکن چونکہ سب کچھ domain اور IP ایڈریس پر منحصر ہے، اس لیے اس کا یہاں ذکر کرنا مناسب ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### DNS { #dns } |
||||
|
|
||||
|
اب آئیے تمام اصل HTTPS حصوں پر توجہ مرکوز کریں۔ |
||||
|
|
||||
|
سب سے پہلے، browser **DNS servers** سے چیک کرے گا کہ **domain کا IP** کیا ہے، اس معاملے میں، `someapp.example.com`۔ |
||||
|
|
||||
|
DNS servers browser کو کوئی مخصوص **IP ایڈریس** بتائیں گے۔ یہ آپ کے server کا وہ عوامی IP ایڈریس ہوگا جو آپ نے DNS servers میں ترتیب دیا تھا۔ |
||||
|
|
||||
|
<img src="/img/deployment/https/https01.drawio.svg"> |
||||
|
|
||||
|
### TLS Handshake کا آغاز { #tls-handshake-start } |
||||
|
|
||||
|
browser پھر اس IP ایڈریس سے **port 443** (HTTPS port) پر مواصلت کرے گا۔ |
||||
|
|
||||
|
مواصلت کا پہلا حصہ صرف client اور server کے درمیان کنکشن قائم کرنا اور خفیہ keys وغیرہ کا فیصلہ کرنا ہے۔ |
||||
|
|
||||
|
<img src="/img/deployment/https/https02.drawio.svg"> |
||||
|
|
||||
|
TLS کنکشن قائم کرنے کے لیے client اور server کے درمیان اس تعامل کو **TLS handshake** کہا جاتا ہے۔ |
||||
|
|
||||
|
### SNI توسیع کے ساتھ TLS { #tls-with-sni-extension } |
||||
|
|
||||
|
server میں ایک مخصوص **IP ایڈریس** کے مخصوص **port** پر صرف **ایک process** سن سکتا ہے۔ اسی IP ایڈریس پر دوسرے ports پر دوسرے processes سن سکتے ہیں، لیکن ہر IP ایڈریس اور port کے مجموعے کے لیے صرف ایک۔ |
||||
|
|
||||
|
TLS (HTTPS) بطور ڈیفالٹ مخصوص port `443` استعمال کرتا ہے۔ تو ہمیں اسی port کی ضرورت ہوگی۔ |
||||
|
|
||||
|
چونکہ اس port پر صرف ایک process سن سکتا ہے، وہ process جو یہ کرے گا وہ **TLS Termination Proxy** ہوگا۔ |
||||
|
|
||||
|
TLS Termination Proxy کے پاس ایک یا زیادہ **TLS certificates** (HTTPS certificates) تک رسائی ہوگی۔ |
||||
|
|
||||
|
اوپر بحث کی گئی **SNI توسیع** کا استعمال کرتے ہوئے، TLS Termination Proxy چیک کرے گا کہ دستیاب TLS (HTTPS) certificates میں سے اسے اس کنکشن کے لیے کون سا استعمال کرنا چاہیے، وہ جو client کی متوقع domain سے مماثل ہو۔ |
||||
|
|
||||
|
اس معاملے میں، یہ `someapp.example.com` کا certificate استعمال کرے گا۔ |
||||
|
|
||||
|
<img src="/img/deployment/https/https03.drawio.svg"> |
||||
|
|
||||
|
client پہلے سے اس ادارے پر **اعتماد** کرتا ہے جس نے وہ TLS certificate تیار کیا (اس معاملے میں Let's Encrypt، لیکن ہم اس کے بارے میں بعد میں بات کریں گے)، تو یہ **تصدیق** کر سکتا ہے کہ certificate درست ہے۔ |
||||
|
|
||||
|
پھر، certificate کا استعمال کرتے ہوئے، client اور TLS Termination Proxy باقی **TCP مواصلت کو encrypt کرنے کا طریقہ فیصلہ** کرتے ہیں۔ اس سے **TLS Handshake** کا حصہ مکمل ہو جاتا ہے۔ |
||||
|
|
||||
|
اس کے بعد، client اور server کے پاس ایک **encrypted TCP کنکشن** ہوتا ہے، یہی وہ چیز ہے جو TLS فراہم کرتا ہے۔ اور پھر وہ اس کنکشن کو اصل **HTTP مواصلت** شروع کرنے کے لیے استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
اور **HTTPS** یہی ہے، یہ بس سادہ **HTTP** ایک **محفوظ TLS کنکشن** کے اندر ہے خالص (غیر encrypted) TCP کنکشن کے بجائے۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
غور کریں کہ مواصلت کی encryption **TCP سطح** پر ہوتی ہے، HTTP سطح پر نہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### HTTPS Request { #https-request } |
||||
|
|
||||
|
اب جب client اور server (خاص طور پر browser اور TLS Termination Proxy) کے پاس ایک **encrypted TCP کنکشن** ہے، تو وہ **HTTP مواصلت** شروع کر سکتے ہیں۔ |
||||
|
|
||||
|
تو، client ایک **HTTPS request** بھیجتا ہے۔ یہ بس ایک encrypted TLS کنکشن کے ذریعے HTTP request ہے۔ |
||||
|
|
||||
|
<img src="/img/deployment/https/https04.drawio.svg"> |
||||
|
|
||||
|
### Request کو Decrypt کرنا { #decrypt-the-request } |
||||
|
|
||||
|
TLS Termination Proxy طے شدہ encryption کا استعمال کرتے ہوئے **request کو decrypt** کرے گا، اور **سادہ (decrypted) HTTP request** ایپلیکیشن چلانے والے process (مثلاً FastAPI ایپلیکیشن چلانے والے Uvicorn کے ساتھ ایک process) کو منتقل کرے گا۔ |
||||
|
|
||||
|
<img src="/img/deployment/https/https05.drawio.svg"> |
||||
|
|
||||
|
### HTTP Response { #http-response } |
||||
|
|
||||
|
ایپلیکیشن request پر عمل کرے گی اور TLS Termination Proxy کو ایک **سادہ (غیر encrypted) HTTP response** بھیجے گی۔ |
||||
|
|
||||
|
<img src="/img/deployment/https/https06.drawio.svg"> |
||||
|
|
||||
|
### HTTPS Response { #https-response } |
||||
|
|
||||
|
TLS Termination Proxy پھر پہلے سے طے شدہ خفیہ نگاری (جو `someapp.example.com` کے certificate سے شروع ہوئی تھی) کا استعمال کرتے ہوئے **response کو encrypt** کرے گا، اور اسے واپس browser کو بھیجے گا۔ |
||||
|
|
||||
|
اس کے بعد، browser تصدیق کرے گا کہ response درست ہے اور صحیح خفیہ key سے encrypted ہے، وغیرہ۔ پھر یہ **response کو decrypt** کرے گا اور اس پر عمل کرے گا۔ |
||||
|
|
||||
|
<img src="/img/deployment/https/https07.drawio.svg"> |
||||
|
|
||||
|
client (browser) جانے گا کہ response صحیح server سے آیا ہے کیونکہ یہ وہ خفیہ نگاری استعمال کر رہا ہے جس پر انہوں نے پہلے **HTTPS certificate** استعمال کرتے ہوئے اتفاق کیا تھا۔ |
||||
|
|
||||
|
### متعدد ایپلیکیشنز { #multiple-applications } |
||||
|
|
||||
|
اسی server (یا servers) میں، **متعدد ایپلیکیشنز** ہو سکتی ہیں، مثلاً دوسرے API پروگرامز یا ڈیٹابیس۔ |
||||
|
|
||||
|
مخصوص IP اور port (ہماری مثال میں TLS Termination Proxy) صرف ایک process سنبھال سکتا ہے لیکن دوسری ایپلیکیشنز/processes بھی server(s) پر چل سکتی ہیں، جب تک کہ وہ **عوامی IP اور port کا وہی مجموعہ** استعمال کرنے کی کوشش نہ کریں۔ |
||||
|
|
||||
|
<img src="/img/deployment/https/https08.drawio.svg"> |
||||
|
|
||||
|
اس طرح، TLS Termination Proxy **متعدد domains** کے لیے، متعدد ایپلیکیشنز کے لیے HTTPS اور certificates سنبھال سکتا ہے، اور پھر ہر معاملے میں requests صحیح ایپلیکیشن کو منتقل کر سکتا ہے۔ |
||||
|
|
||||
|
### Certificate کی تجدید { #certificate-renewal } |
||||
|
|
||||
|
مستقبل میں کسی وقت، ہر certificate **ختم** ہو جائے گا (حاصل کرنے کے تقریباً 3 ماہ بعد)۔ |
||||
|
|
||||
|
اور پھر، ایک اور پروگرام ہوگا (بعض اوقات یہ ایک اور پروگرام ہوتا ہے، بعض اوقات یہ وہی TLS Termination Proxy ہو سکتا ہے) جو Let's Encrypt سے بات کرے گا، اور certificate(s) کی تجدید کرے گا۔ |
||||
|
|
||||
|
<img src="/img/deployment/https/https.drawio.svg"> |
||||
|
|
||||
|
**TLS certificates** ایک **domain name سے منسلک** ہوتے ہیں، IP ایڈریس سے نہیں۔ |
||||
|
|
||||
|
تو، certificates کی تجدید کے لیے، تجدیدی پروگرام کو اتھارٹی (Let's Encrypt) کو **ثابت** کرنا ہوگا کہ یہ واقعی اس domain کا **"مالک" ہے اور اسے کنٹرول** کرتا ہے۔ |
||||
|
|
||||
|
ایسا کرنے کے لیے، اور مختلف ایپلیکیشن کی ضروریات کو پورا کرنے کے لیے، یہ کئی طریقوں سے کر سکتا ہے۔ کچھ مقبول طریقے یہ ہیں: |
||||
|
|
||||
|
* **کچھ DNS records میں ترمیم**۔ |
||||
|
* اس کے لیے، تجدیدی پروگرام کو DNS provider کی APIs کی حمایت کرنی ہوگی، تو، آپ جو DNS provider استعمال کر رہے ہیں اس پر منحصر ہے، یہ اختیار ہو بھی سکتا ہے اور نہیں بھی۔ |
||||
|
* domain سے منسلک عوامی IP ایڈریس پر **server کے طور پر چلنا** (کم از کم certificate حصول کے عمل کے دوران)۔ |
||||
|
* جیسا کہ ہم نے اوپر کہا، مخصوص IP اور port پر صرف ایک process سن سکتا ہے۔ |
||||
|
* یہ ان وجوہات میں سے ایک ہے جس کی وجہ سے یہ بہت مفید ہے جب وہی TLS Termination Proxy certificate کی تجدید کے عمل کا بھی خیال رکھے۔ |
||||
|
* ورنہ، آپ کو TLS Termination Proxy کو عارضی طور پر بند کرنا پڑ سکتا ہے، certificates حاصل کرنے کے لیے تجدیدی پروگرام شروع کرنا، پھر انہیں TLS Termination Proxy کے ساتھ ترتیب دینا، اور پھر TLS Termination Proxy کو دوبارہ شروع کرنا۔ یہ مثالی نہیں ہے، کیونکہ TLS Termination Proxy بند ہونے کے دوران آپ کی app(s) دستیاب نہیں ہوں گی۔ |
||||
|
|
||||
|
یہ سارا تجدید کا عمل، جبکہ ابھی بھی app کو خدمت فراہم کر رہے ہوں، ان اصل وجوہات میں سے ایک ہے جس کی وجہ سے آپ HTTPS سنبھالنے کے لیے TLS Termination Proxy کے ساتھ **الگ نظام** رکھنا چاہیں گے بجائے اس کے کہ TLS certificates کو براہ راست application server (مثلاً Uvicorn) کے ساتھ استعمال کریں۔ |
||||
|
|
||||
|
## Proxy Forwarded Headers { #proxy-forwarded-headers } |
||||
|
|
||||
|
HTTPS سنبھالنے کے لیے proxy استعمال کرتے وقت، آپ کا **application server** (مثلاً FastAPI CLI کے ذریعے Uvicorn) HTTPS کے عمل کے بارے میں کچھ نہیں جانتا، یہ **TLS Termination Proxy** کے ساتھ سادہ HTTP میں مواصلت کرتا ہے۔ |
||||
|
|
||||
|
یہ **proxy** عام طور پر request کو **application server** کو منتقل کرنے سے پہلے فوری طور پر کچھ HTTP headers مقرر کرتا ہے، تاکہ application server کو بتائے کہ request proxy کے ذریعے **آگے بھیجی** جا رہی ہے۔ |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
proxy headers یہ ہیں: |
||||
|
|
||||
|
* [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For) |
||||
|
* [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto) |
||||
|
* [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host) |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
تاہم، چونکہ **application server** نہیں جانتا کہ یہ ایک قابل اعتماد **proxy** کے پیچھے ہے، بطور ڈیفالٹ، یہ ان headers پر اعتماد نہیں کرے گا۔ |
||||
|
|
||||
|
لیکن آپ **application server** کو ترتیب دے سکتے ہیں کہ وہ **proxy** کی طرف سے بھیجے گئے *forwarded* headers پر اعتماد کرے۔ اگر آپ FastAPI CLI استعمال کر رہے ہیں، تو آپ *CLI Option* `--forwarded-allow-ips` استعمال کر سکتے ہیں تاکہ اسے بتائیں کہ کن IPs سے آنے والے *forwarded* headers پر اعتماد کرنا ہے۔ |
||||
|
|
||||
|
مثال کے طور پر، اگر **application server** صرف قابل اعتماد **proxy** سے مواصلت وصول کر رہا ہے، تو آپ اسے `--forwarded-allow-ips="*"` پر سیٹ کر سکتے ہیں تاکہ یہ تمام آنے والی IPs پر اعتماد کرے، کیونکہ اسے صرف **proxy** کے IP سے requests ملیں گی۔ |
||||
|
|
||||
|
اس طرح ایپلیکیشن جان سکے گی کہ اس کا اپنا عوامی URL کیا ہے، آیا یہ HTTPS استعمال کر رہی ہے، domain، وغیرہ۔ |
||||
|
|
||||
|
یہ مثال کے طور پر redirects کو صحیح طریقے سے سنبھالنے کے لیے مفید ہوگا۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
آپ اس کے بارے میں مزید [Behind a Proxy - Enable Proxy Forwarded Headers](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers) کی دستاویزات میں جان سکتے ہیں |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## خلاصہ { #recap } |
||||
|
|
||||
|
**HTTPS** ہونا بہت اہم ہے، اور زیادہ تر معاملات میں کافی **ضروری** ہے۔ بحیثیت developer HTTPS کے حوالے سے آپ کی زیادہ تر محنت بس **ان تصورات کو سمجھنے** اور یہ جاننے میں لگتی ہے کہ یہ کیسے کام کرتے ہیں۔ |
||||
|
|
||||
|
لیکن ایک بار جب آپ **developers کے لیے HTTPS** کی بنیادی معلومات جان لیں تو آپ آسانی سے مختلف ٹولز کو ملا اور ترتیب دے سکتے ہیں تاکہ سب کچھ آسان طریقے سے منظم ہو سکے۔ |
||||
|
|
||||
|
اگلے چند ابواب میں، میں آپ کو **FastAPI** ایپلیکیشنز کے لیے **HTTPS** ترتیب دینے کی کئی ٹھوس مثالیں دکھاؤں گا۔ 🔒 |
||||
@ -0,0 +1,23 @@ |
|||||
|
# Deployment { #deployment } |
||||
|
|
||||
|
**FastAPI** ایپلیکیشن کو deploy کرنا نسبتاً آسان ہے۔ |
||||
|
|
||||
|
## Deployment کا مطلب کیا ہے { #what-does-deployment-mean } |
||||
|
|
||||
|
کسی ایپلیکیشن کو **deploy** کرنے کا مطلب ہے وہ ضروری اقدامات کرنا جن سے یہ **صارفین کے لیے دستیاب** ہو جائے۔ |
||||
|
|
||||
|
**web API** کے لیے، اس کا عام طور پر مطلب ہے اسے ایک **remote machine** پر رکھنا، ایک ایسے **server program** کے ساتھ جو اچھی کارکردگی، استحکام وغیرہ فراہم کرے، تاکہ آپ کے **صارفین** ایپلیکیشن تک مؤثر طریقے سے اور بغیر کسی رکاوٹ یا مسائل کے **رسائی** حاصل کر سکیں۔ |
||||
|
|
||||
|
یہ **development** کے مراحل سے مختلف ہے، جہاں آپ مسلسل کوڈ تبدیل کرتے رہتے ہیں، اسے توڑتے اور ٹھیک کرتے ہیں، development server کو بند اور دوبارہ شروع کرتے ہیں، وغیرہ۔ |
||||
|
|
||||
|
## Deployment کی حکمت عملیاں { #deployment-strategies } |
||||
|
|
||||
|
آپ کے مخصوص استعمال کے معاملے اور آپ جو ٹولز استعمال کرتے ہیں ان کے لحاظ سے اسے کرنے کے کئی طریقے ہیں۔ |
||||
|
|
||||
|
آپ خود ٹولز کے مجموعے سے **server deploy** کر سکتے ہیں، آپ **cloud service** استعمال کر سکتے ہیں جو آپ کے لیے کچھ کام کرے، یا دوسرے ممکنہ اختیارات۔ |
||||
|
|
||||
|
مثال کے طور پر، ہم نے، FastAPI کے پیچھے کی ٹیم نے، [**FastAPI Cloud**](https://fastapicloud.com) بنایا ہے تاکہ FastAPI ایپس کو cloud پر deploy کرنا ممکنہ حد تک آسان ہو، FastAPI کے ساتھ کام کرنے جیسے developer experience کے ساتھ۔ |
||||
|
|
||||
|
میں آپ کو کچھ اہم تصورات دکھاؤں گا جو آپ کو **FastAPI** ایپلیکیشن deploy کرتے وقت ذہن میں رکھنے چاہئیں (اگرچہ ان میں سے زیادہ تر کسی بھی دوسری قسم کی web ایپلیکیشن پر لاگو ہوتے ہیں)۔ |
||||
|
|
||||
|
آپ اگلے حصوں میں ذہن میں رکھنے کے لیے مزید تفصیلات اور کچھ تکنیکیں دیکھیں گے۔ ✨ |
||||
@ -0,0 +1,157 @@ |
|||||
|
# Server کو دستی طور پر چلائیں { #run-a-server-manually } |
||||
|
|
||||
|
## `fastapi run` Command استعمال کریں { #use-the-fastapi-run-command } |
||||
|
|
||||
|
مختصراً، اپنی FastAPI ایپلیکیشن کو چلانے کے لیے `fastapi run` استعمال کریں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:solid">main.py</u> |
||||
|
|
||||
|
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting production server 🚀 |
||||
|
|
||||
|
Searching for package file structure from directories |
||||
|
with <font color="#3465A4">__init__.py</font> files |
||||
|
Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font> |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> module </font></span> 🐍 main.py |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> code </font></span> Importing the FastAPI app object from the module with |
||||
|
the following code: |
||||
|
|
||||
|
<u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u> |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> app </font></span> Using import string: <font color="#3465A4">main:app</font> |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font> |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000/docs</u></font> |
||||
|
|
||||
|
Logs: |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>2306215</b></font><b>]</b> |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup. |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete. |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font> <b>(</b>Press CTRL+C |
||||
|
to quit<b>)</b> |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
یہ زیادہ تر معاملات میں کام کرے گا۔ 😎 |
||||
|
|
||||
|
آپ اس command کو مثلاً اپنی **FastAPI** app کو container میں، server میں وغیرہ شروع کرنے کے لیے استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
## ASGI Servers { #asgi-servers } |
||||
|
|
||||
|
آئیے تفصیلات میں تھوڑا گہرائی میں جائیں۔ |
||||
|
|
||||
|
FastAPI ایک معیار استعمال کرتا ہے جو Python web frameworks اور servers بنانے کے لیے ہے جسے <abbr title="Asynchronous Server Gateway Interface">ASGI</abbr> کہتے ہیں۔ FastAPI ایک ASGI web framework ہے۔ |
||||
|
|
||||
|
remote server machine پر **FastAPI** ایپلیکیشن (یا کوئی بھی ASGI ایپلیکیشن) چلانے کے لیے آپ کو بنیادی طور پر ایک ASGI server پروگرام جیسے **Uvicorn** کی ضرورت ہے، یہ وہ ہے جو `fastapi` command میں بطور ڈیفالٹ آتا ہے۔ |
||||
|
|
||||
|
کئی متبادل ہیں، بشمول: |
||||
|
|
||||
|
* [Uvicorn](https://www.uvicorn.dev/): ایک اعلیٰ کارکردگی والا ASGI server۔ |
||||
|
* [Hypercorn](https://hypercorn.readthedocs.io/): HTTP/2 اور Trio کے ساتھ ہم آہنگ ایک ASGI server اور دیگر خصوصیات۔ |
||||
|
* [Daphne](https://github.com/django/daphne): Django Channels کے لیے بنایا گیا ASGI server۔ |
||||
|
* [Granian](https://github.com/emmett-framework/granian): Python ایپلیکیشنز کے لیے ایک Rust HTTP server۔ |
||||
|
* [NGINX Unit](https://unit.nginx.org/howto/fastapi/): NGINX Unit ایک ہلکا اور ورسٹائل web application runtime ہے۔ |
||||
|
|
||||
|
## Server Machine اور Server Program { #server-machine-and-server-program } |
||||
|
|
||||
|
ناموں کے بارے میں ایک چھوٹی سی بات ذہن میں رکھنے کی ہے۔ 💡 |
||||
|
|
||||
|
"**server**" کا لفظ عام طور پر remote/cloud کمپیوٹر (فزیکل یا virtual machine) اور اس مشین پر چلنے والے پروگرام (مثلاً Uvicorn) دونوں کے لیے استعمال ہوتا ہے۔ |
||||
|
|
||||
|
بس ذہن میں رکھیں کہ جب آپ عمومی طور پر "server" پڑھیں تو اس سے ان دو چیزوں میں سے کوئی ایک مراد ہو سکتی ہے۔ |
||||
|
|
||||
|
remote machine کا حوالہ دیتے وقت، اسے عام طور پر **server** کہا جاتا ہے، لیکن **machine**، **VM** (virtual machine)، **node** بھی کہتے ہیں۔ یہ سب کسی قسم کی remote machine کا حوالہ دیتے ہیں، عام طور پر Linux چلاتی ہوئی، جہاں آپ پروگرامز چلاتے ہیں۔ |
||||
|
|
||||
|
## Server Program انسٹال کریں { #install-the-server-program } |
||||
|
|
||||
|
جب آپ FastAPI انسٹال کرتے ہیں، تو یہ ایک production server، Uvicorn، کے ساتھ آتا ہے، اور آپ اسے `fastapi run` command سے شروع کر سکتے ہیں۔ |
||||
|
|
||||
|
لیکن آپ ASGI server کو دستی طور پر بھی انسٹال کر سکتے ہیں۔ |
||||
|
|
||||
|
اس بات کو یقینی بنائیں کہ آپ [virtual environment](../virtual-environments.md) بنائیں، اسے فعال کریں، اور پھر آپ server ایپلیکیشن انسٹال کر سکتے ہیں۔ |
||||
|
|
||||
|
مثال کے طور پر، Uvicorn انسٹال کرنے کے لیے: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ pip install "uvicorn[standard]" |
||||
|
|
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
کسی بھی دوسرے ASGI server پروگرام پر بھی اسی طرح کا عمل لاگو ہوگا۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
`standard` شامل کرنے سے، Uvicorn کچھ تجویز کردہ اضافی dependencies انسٹال اور استعمال کرے گا۔ |
||||
|
|
||||
|
اس میں `uvloop` شامل ہے، `asyncio` کا اعلیٰ کارکردگی والا متبادل، جو بڑی concurrency کارکردگی میں اضافہ فراہم کرتا ہے۔ |
||||
|
|
||||
|
جب آپ FastAPI کو `pip install "fastapi[standard]"` جیسی کسی چیز سے انسٹال کرتے ہیں تو آپ کو `uvicorn[standard]` بھی مل جاتا ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Server Program چلائیں { #run-the-server-program } |
||||
|
|
||||
|
اگر آپ نے ASGI server دستی طور پر انسٹال کیا ہے، تو آپ کو عام طور پر اپنی FastAPI ایپلیکیشن import کرنے کے لیے ایک خاص فارمیٹ میں import string دینی ہوگی: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ uvicorn main:app --host 0.0.0.0 --port 80 |
||||
|
|
||||
|
<span style="color: green;">INFO</span>: Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit) |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
/// note | نوٹ |
||||
|
|
||||
|
`uvicorn main:app` command کا مطلب ہے: |
||||
|
|
||||
|
* `main`: فائل `main.py` (Python "module")۔ |
||||
|
* `app`: وہ آبجیکٹ جو `main.py` کے اندر `app = FastAPI()` لائن سے بنایا گیا۔ |
||||
|
|
||||
|
یہ اس کے مساوی ہے: |
||||
|
|
||||
|
```Python |
||||
|
from main import app |
||||
|
``` |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
ہر متبادل ASGI server پروگرام کی ایک مماثل command ہوگی، آپ ان کی متعلقہ دستاویزات میں مزید پڑھ سکتے ہیں۔ |
||||
|
|
||||
|
/// warning | انتباہ |
||||
|
|
||||
|
Uvicorn اور دوسرے servers ایک `--reload` اختیار فراہم کرتے ہیں جو development کے دوران مفید ہے۔ |
||||
|
|
||||
|
`--reload` اختیار بہت زیادہ وسائل استعمال کرتا ہے، زیادہ غیر مستحکم ہے، وغیرہ۔ |
||||
|
|
||||
|
یہ **development** کے دوران بہت مدد کرتا ہے، لیکن آپ کو **production** میں اسے استعمال **نہیں کرنا** چاہیے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Deployment کے تصورات { #deployment-concepts } |
||||
|
|
||||
|
یہ مثالیں server پروگرام (مثلاً Uvicorn) کو **ایک واحد process** شروع کرتے ہوئے چلاتی ہیں، تمام IPs (`0.0.0.0`) پر ایک پہلے سے طے شدہ port (مثلاً `80`) پر سنتے ہوئے۔ |
||||
|
|
||||
|
یہ بنیادی خیال ہے۔ لیکن آپ شاید کچھ اضافی چیزوں کا خیال رکھنا چاہیں گے، جیسے: |
||||
|
|
||||
|
* سیکیورٹی - HTTPS |
||||
|
* شروع ہونے پر چلنا |
||||
|
* دوبارہ شروع ہونا |
||||
|
* نقل (چلنے والے processes کی تعداد) |
||||
|
* میموری |
||||
|
* شروع ہونے سے پہلے کے مراحل |
||||
|
|
||||
|
میں آپ کو اگلے ابواب میں ان میں سے ہر تصور کے بارے میں مزید بتاؤں گا، ان کے بارے میں سوچنے کا طریقہ، اور انہیں سنبھالنے کی حکمت عملیوں کی کچھ ٹھوس مثالیں۔ 🚀 |
||||
@ -0,0 +1,139 @@ |
|||||
|
# Server Workers - Uvicorn with Workers { #server-workers-uvicorn-with-workers } |
||||
|
|
||||
|
آئیے پہلے سے ان deployment تصورات کو دوبارہ دیکھتے ہیں: |
||||
|
|
||||
|
* سیکیورٹی - HTTPS |
||||
|
* شروع ہونے پر چلنا |
||||
|
* دوبارہ شروع ہونا |
||||
|
* **نقل (چلنے والے processes کی تعداد)** |
||||
|
* میموری |
||||
|
* شروع ہونے سے پہلے کے مراحل |
||||
|
|
||||
|
اب تک، دستاویزات کے تمام ٹیوٹوریلز کے ساتھ، آپ شاید ایک **server پروگرام** چلا رہے تھے، مثلاً `fastapi` command استعمال کرتے ہوئے جو Uvicorn چلاتا ہے، ایک **واحد process** میں۔ |
||||
|
|
||||
|
ایپلیکیشنز deploy کرتے وقت آپ شاید **متعدد cores** سے فائدہ اٹھانے اور زیادہ requests سنبھالنے کے لیے **processes کی نقل** رکھنا چاہیں گے۔ |
||||
|
|
||||
|
جیسا کہ آپ نے [Deployment تصورات](concepts.md) کے پچھلے باب میں دیکھا، اس کے لیے متعدد حکمت عملیاں ہیں۔ |
||||
|
|
||||
|
یہاں میں آپ کو دکھاؤں گا کہ `fastapi` command یا `uvicorn` command براہ راست استعمال کرتے ہوئے **worker processes** کے ساتھ **Uvicorn** کیسے استعمال کریں۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
اگر آپ containers استعمال کر رہے ہیں، مثلاً Docker یا Kubernetes کے ساتھ، تو میں اگلے باب میں اس کے بارے میں مزید بتاؤں گا: [FastAPI in Containers - Docker](docker.md)۔ |
||||
|
|
||||
|
خاص طور پر، **Kubernetes** پر چلاتے وقت آپ شاید workers استعمال **نہیں** کرنا چاہیں گے بلکہ **ہر container میں ایک واحد Uvicorn process** چلائیں گے، لیکن میں اس کے بارے میں اس باب میں بعد میں بتاؤں گا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## متعدد Workers { #multiple-workers } |
||||
|
|
||||
|
آپ `--workers` command line اختیار کے ساتھ متعدد workers شروع کر سکتے ہیں: |
||||
|
|
||||
|
//// tab | `fastapi` |
||||
|
|
||||
|
اگر آپ `fastapi` command استعمال کرتے ہیں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ <font color="#4E9A06">fastapi</font> run --workers 4 <u style="text-decoration-style:solid">main.py</u> |
||||
|
|
||||
|
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting production server 🚀 |
||||
|
|
||||
|
Searching for package file structure from directories with |
||||
|
<font color="#3465A4">__init__.py</font> files |
||||
|
Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font> |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> module </font></span> 🐍 main.py |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> code </font></span> Importing the FastAPI app object from the module with the |
||||
|
following code: |
||||
|
|
||||
|
<u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u> |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> app </font></span> Using import string: <font color="#3465A4">main:app</font> |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font> |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000/docs</u></font> |
||||
|
|
||||
|
Logs: |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font> <b>(</b>Press CTRL+C to |
||||
|
quit<b>)</b> |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started parent process <b>[</b><font color="#34E2E2"><b>27365</b></font><b>]</b> |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27368</b></font><b>]</b> |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27369</b></font><b>]</b> |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27370</b></font><b>]</b> |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27367</b></font><b>]</b> |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup. |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup. |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup. |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup. |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete. |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete. |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete. |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete. |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | `uvicorn` |
||||
|
|
||||
|
اگر آپ `uvicorn` command براہ راست استعمال کرنا چاہیں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4 |
||||
|
<font color="#A6E22E">INFO</font>: Uvicorn running on <b>http://0.0.0.0:8080</b> (Press CTRL+C to quit) |
||||
|
<font color="#A6E22E">INFO</font>: Started parent process [<font color="#A1EFE4"><b>27365</b></font>] |
||||
|
<font color="#A6E22E">INFO</font>: Started server process [<font color="#A1EFE4">27368</font>] |
||||
|
<font color="#A6E22E">INFO</font>: Waiting for application startup. |
||||
|
<font color="#A6E22E">INFO</font>: Application startup complete. |
||||
|
<font color="#A6E22E">INFO</font>: Started server process [<font color="#A1EFE4">27369</font>] |
||||
|
<font color="#A6E22E">INFO</font>: Waiting for application startup. |
||||
|
<font color="#A6E22E">INFO</font>: Application startup complete. |
||||
|
<font color="#A6E22E">INFO</font>: Started server process [<font color="#A1EFE4">27370</font>] |
||||
|
<font color="#A6E22E">INFO</font>: Waiting for application startup. |
||||
|
<font color="#A6E22E">INFO</font>: Application startup complete. |
||||
|
<font color="#A6E22E">INFO</font>: Started server process [<font color="#A1EFE4">27367</font>] |
||||
|
<font color="#A6E22E">INFO</font>: Waiting for application startup. |
||||
|
<font color="#A6E22E">INFO</font>: Application startup complete. |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
یہاں واحد نیا اختیار `--workers` ہے جو Uvicorn کو 4 worker processes شروع کرنے کو کہتا ہے۔ |
||||
|
|
||||
|
آپ یہ بھی دیکھ سکتے ہیں کہ یہ ہر process کا **PID** دکھاتا ہے، parent process (یہ **process manager** ہے) کے لیے `27365` اور ہر worker process کے لیے ایک: `27368`، `27369`، `27370`، اور `27367`۔ |
||||
|
|
||||
|
## Deployment کے تصورات { #deployment-concepts } |
||||
|
|
||||
|
یہاں آپ نے دیکھا کہ ایپلیکیشن کے عمل کو **متوازی** بنانے، CPU میں **متعدد cores** سے فائدہ اٹھانے، اور **زیادہ requests** فراہم کرنے کے قابل ہونے کے لیے متعدد **workers** کیسے استعمال کریں۔ |
||||
|
|
||||
|
اوپر کی deployment تصورات کی فہرست سے، workers استعمال کرنا بنیادی طور پر **نقل** کے حصے میں مدد کرے گا، اور تھوڑا سا **دوبارہ شروع ہونے** میں، لیکن آپ کو ابھی بھی باقیوں کا خیال رکھنا ہوگا: |
||||
|
|
||||
|
* **سیکیورٹی - HTTPS** |
||||
|
* **شروع ہونے پر چلنا** |
||||
|
* ***دوبارہ شروع ہونا*** |
||||
|
* نقل (چلنے والے processes کی تعداد) |
||||
|
* **میموری** |
||||
|
* **شروع ہونے سے پہلے کے مراحل** |
||||
|
|
||||
|
## Containers اور Docker { #containers-and-docker } |
||||
|
|
||||
|
[FastAPI in Containers - Docker](docker.md) کے بارے میں اگلے باب میں میں آپ کو کچھ حکمت عملیاں بتاؤں گا جو آپ دوسرے **deployment تصورات** سنبھالنے کے لیے استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
میں آپ کو دکھاؤں گا کہ ایک واحد Uvicorn process چلانے کے لیے **شروع سے اپنی خود کی image کیسے بنائیں**۔ یہ ایک آسان عمل ہے اور شاید یہی وہ چیز ہے جو آپ **Kubernetes** جیسے تقسیم شدہ container management system استعمال کرتے وقت کرنا چاہیں گے۔ |
||||
|
|
||||
|
## خلاصہ { #recap } |
||||
|
|
||||
|
آپ **multi-core CPUs** سے فائدہ اٹھانے اور **متوازی طور پر متعدد processes** چلانے کے لیے `fastapi` یا `uvicorn` commands کے ساتھ `--workers` CLI اختیار استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
آپ ان ٹولز اور خیالات کو استعمال کر سکتے ہیں اگر آپ خود deployment تصورات کا خیال رکھتے ہوئے **اپنا خود کا deployment system** ترتیب دے رہے ہیں۔ |
||||
|
|
||||
|
containers (مثلاً Docker اور Kubernetes) کے ساتھ **FastAPI** کے بارے میں جاننے کے لیے اگلا باب دیکھیں۔ آپ دیکھیں گے کہ ان ٹولز میں دوسرے **deployment تصورات** کو بھی حل کرنے کے آسان طریقے ہیں۔ ✨ |
||||
@ -0,0 +1,93 @@ |
|||||
|
# FastAPI ورژنز کے بارے میں { #about-fastapi-versions } |
||||
|
|
||||
|
**FastAPI** پہلے سے بہت سی ایپلیکیشنز اور سسٹمز میں production میں استعمال ہو رہا ہے۔ اور ٹیسٹ کوریج 100% پر رکھی جاتی ہے۔ لیکن اس کی ترقی ابھی بھی تیزی سے جاری ہے۔ |
||||
|
|
||||
|
نئے فیچرز اکثر شامل کیے جاتے ہیں، bugs باقاعدگی سے ٹھیک کیے جاتے ہیں، اور کوڈ مسلسل بہتر ہو رہا ہے۔ |
||||
|
|
||||
|
اسی لیے موجودہ ورژن ابھی بھی `0.x.x` ہیں، یہ ظاہر کرتا ہے کہ ہر ورژن میں ممکنہ طور پر ٹوٹنے والی تبدیلیاں ہو سکتی ہیں۔ یہ [Semantic Versioning](https://semver.org/) کے ضوابط کی پیروی کرتا ہے۔ |
||||
|
|
||||
|
آپ ابھی **FastAPI** کے ساتھ production ایپلیکیشنز بنا سکتے ہیں (اور شاید کچھ عرصے سے بنا رہے ہیں)، آپ کو بس یقینی بنانا ہے کہ آپ ایسا ورژن استعمال کریں جو آپ کے باقی کوڈ کے ساتھ درست طریقے سے کام کرے۔ |
||||
|
|
||||
|
## اپنا `fastapi` ورژن مقرر کریں { #pin-your-fastapi-version } |
||||
|
|
||||
|
سب سے پہلے آپ کو **FastAPI** کا وہ ورژن "pin" کرنا چاہیے جو مخصوص تازہ ترین ورژن ہو جو آپ جانتے ہیں کہ آپ کی ایپلیکیشن کے ساتھ درست طریقے سے کام کرتا ہے۔ |
||||
|
|
||||
|
مثال کے طور پر، فرض کریں کہ آپ اپنی app میں ورژن `0.112.0` استعمال کر رہے ہیں۔ |
||||
|
|
||||
|
اگر آپ `requirements.txt` فائل استعمال کرتے ہیں تو آپ ورژن اس طرح مقرر کر سکتے ہیں: |
||||
|
|
||||
|
```txt |
||||
|
fastapi[standard]==0.112.0 |
||||
|
``` |
||||
|
|
||||
|
اس کا مطلب ہوگا کہ آپ بالکل ورژن `0.112.0` استعمال کریں گے۔ |
||||
|
|
||||
|
یا آپ اسے اس طرح بھی pin کر سکتے ہیں: |
||||
|
|
||||
|
```txt |
||||
|
fastapi[standard]>=0.112.0,<0.113.0 |
||||
|
``` |
||||
|
|
||||
|
اس کا مطلب ہوگا کہ آپ `0.112.0` یا اس سے اوپر کے ورژن استعمال کریں گے، لیکن `0.113.0` سے کم، مثلاً ورژن `0.112.2` بھی قبول ہوگا۔ |
||||
|
|
||||
|
اگر آپ اپنی تنصیبات منظم کرنے کے لیے کوئی اور ٹول استعمال کرتے ہیں، جیسے `uv`، Poetry، Pipenv، یا دوسرے، ان سب کے پاس ایسا طریقہ ہے جو آپ اپنے packages کے لیے مخصوص ورژنز تعین کرنے کے لیے استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
## دستیاب ورژنز { #available-versions } |
||||
|
|
||||
|
آپ دستیاب ورژنز دیکھ سکتے ہیں (مثلاً یہ چیک کرنے کے لیے کہ موجودہ تازہ ترین کون سا ہے) [Release Notes](../release-notes.md) میں۔ |
||||
|
|
||||
|
## ورژنز کے بارے میں { #about-versions } |
||||
|
|
||||
|
Semantic Versioning ضوابط کی پیروی کرتے ہوئے، `1.0.0` سے نیچے کوئی بھی ورژن ممکنہ طور پر ٹوٹنے والی تبدیلیاں شامل کر سکتا ہے۔ |
||||
|
|
||||
|
FastAPI اس ضابطے کی بھی پیروی کرتا ہے کہ کوئی بھی "PATCH" ورژن تبدیلی bug fixes اور غیر ٹوٹنے والی تبدیلیوں کے لیے ہے۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
"PATCH" آخری نمبر ہے، مثلاً `0.2.3` میں PATCH ورژن `3` ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
تو، آپ کو اس طرح کے ورژن پر pin کرنے کے قابل ہونا چاہیے: |
||||
|
|
||||
|
```txt |
||||
|
fastapi>=0.45.0,<0.46.0 |
||||
|
``` |
||||
|
|
||||
|
ٹوٹنے والی تبدیلیاں اور نئے فیچرز "MINOR" ورژنز میں شامل کیے جاتے ہیں۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
"MINOR" درمیان کا نمبر ہے، مثلاً `0.2.3` میں MINOR ورژن `2` ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## FastAPI ورژنز اپ گریڈ کرنا { #upgrading-the-fastapi-versions } |
||||
|
|
||||
|
آپ کو اپنی app کے لیے ٹیسٹس شامل کرنے چاہئیں۔ |
||||
|
|
||||
|
**FastAPI** کے ساتھ یہ بہت آسان ہے (Starlette کی بدولت)، دستاویزات دیکھیں: [Testing](../tutorial/testing.md) |
||||
|
|
||||
|
ٹیسٹس ہونے کے بعد، آپ **FastAPI** ورژن کو زیادہ حالیہ میں اپ گریڈ کر سکتے ہیں، اور اپنے ٹیسٹس چلا کر یقینی بنا سکتے ہیں کہ آپ کا تمام کوڈ درست طریقے سے کام کر رہا ہے۔ |
||||
|
|
||||
|
اگر سب کچھ کام کر رہا ہے، یا ضروری تبدیلیاں کرنے کے بعد، اور آپ کے تمام ٹیسٹس پاس ہو رہے ہیں، تو آپ اپنا `fastapi` اس نئے حالیہ ورژن پر pin کر سکتے ہیں۔ |
||||
|
|
||||
|
## Starlette کے بارے میں { #about-starlette } |
||||
|
|
||||
|
آپ کو `starlette` کا ورژن pin نہیں کرنا چاہیے۔ |
||||
|
|
||||
|
**FastAPI** کے مختلف ورژنز Starlette کا ایک مخصوص نیا ورژن استعمال کریں گے۔ |
||||
|
|
||||
|
تو، آپ بس **FastAPI** کو صحیح Starlette ورژن استعمال کرنے دیں۔ |
||||
|
|
||||
|
## Pydantic کے بارے میں { #about-pydantic } |
||||
|
|
||||
|
Pydantic **FastAPI** کے ٹیسٹس کو اپنے ٹیسٹس میں شامل کرتا ہے، تو Pydantic کے نئے ورژنز (`1.0.0` سے اوپر) ہمیشہ FastAPI کے ساتھ ہم آہنگ ہوتے ہیں۔ |
||||
|
|
||||
|
آپ Pydantic کو `1.0.0` سے اوپر کسی بھی ایسے ورژن پر pin کر سکتے ہیں جو آپ کے لیے کام کرے۔ |
||||
|
|
||||
|
مثال کے طور پر: |
||||
|
|
||||
|
```txt |
||||
|
pydantic>=2.7.0,<3.0.0 |
||||
|
``` |
||||
@ -0,0 +1,23 @@ |
|||||
|
# Editor Support { #editor-support } |
||||
|
|
||||
|
سرکاری [FastAPI Extension](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) آپ کے FastAPI development workflow کو *path operation* کی دریافت، navigation، نیز FastAPI Cloud deployment، اور لائیو log streaming کے ساتھ بہتر بناتا ہے۔ |
||||
|
|
||||
|
Extension کے بارے میں مزید تفصیلات کے لیے، [GitHub repository](https://github.com/fastapi/fastapi-vscode) پر README دیکھیں۔ |
||||
|
|
||||
|
## سیٹ اپ اور Installation { #setup-and-installation } |
||||
|
|
||||
|
**FastAPI Extension** [VS Code](https://code.visualstudio.com/) اور [Cursor](https://www.cursor.com/) دونوں کے لیے دستیاب ہے۔ اسے ہر editor میں Extensions پینل سے "FastAPI" تلاش کرکے اور **FastAPI Labs** کی شائع کردہ extension منتخب کرکے براہ راست install کیا جا سکتا ہے۔ یہ extension browser پر مبنی editors جیسے [vscode.dev](https://vscode.dev) اور [github.dev](https://github.dev) میں بھی کام کرتا ہے۔ |
||||
|
|
||||
|
### Application Discovery { #application-discovery } |
||||
|
|
||||
|
بطور default، extension آپ کے workspace میں `FastAPI()` instantiate کرنے والی فائلوں کو scan کرکے خودکار طور پر FastAPI applications دریافت کرے گا۔ اگر auto-detection آپ کے project structure کے لیے کام نہ کرے، تو آپ `pyproject.toml` میں `[tool.fastapi]` کے ذریعے یا `fastapi.entryPoint` VS Code setting میں module notation (مثلاً `myapp.main:app`) استعمال کرکے entrypoint بتا سکتے ہیں۔ |
||||
|
|
||||
|
## Features { #features } |
||||
|
|
||||
|
- **Path Operation Explorer** - آپ کی application میں تمام <dfn title="routes, endpoints">*path operations*</dfn> کا ایک sidebar tree view۔ کسی بھی route یا router definition تک جانے کے لیے کلک کریں۔ |
||||
|
- **Route Search** - <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>E</kbd> (macOS پر: <kbd>Cmd</kbd> + <kbd>Shift</kbd> + <kbd>E</kbd>) سے path، method، یا name سے تلاش کریں۔ |
||||
|
- **CodeLens Navigation** - Test client calls (مثلاً `client.get('/items')`) کے اوپر کلک کرنے والے links جو مماثل *path operation* تک لے جاتے ہیں تاکہ tests اور implementation کے درمیان تیز navigation ہو۔ |
||||
|
- **Deploy to FastAPI Cloud** - ایک کلک سے اپنی app کو [FastAPI Cloud](https://fastapicloud.com/) پر deploy کریں۔ |
||||
|
- **Stream Application Logs** - اپنی FastAPI Cloud پر deploy شدہ application سے level filtering اور text search کے ساتھ real-time log streaming۔ |
||||
|
|
||||
|
اگر آپ extension کی features سے واقف ہونا چاہتے ہیں، تو Command Palette (<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> یا macOS پر: <kbd>Cmd</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd>) کھول کر "Welcome: Open walkthrough..." منتخب کریں اور پھر "Get started with FastAPI" walkthrough چنیں۔ |
||||
@ -0,0 +1,298 @@ |
|||||
|
# Environment Variables { #environment-variables } |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
اگر آپ پہلے سے جانتے ہیں کہ "environment variables" کیا ہیں اور انہیں کیسے استعمال کرتے ہیں، تو آزادانہ طور پر اسے چھوڑ دیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
ایک environment variable (جسے "**env var**" بھی کہا جاتا ہے) ایک ایسا variable ہے جو Python code سے **باہر**، **operating system** میں رہتا ہے، اور آپ کا Python code (یا دوسرے programs بھی) اسے پڑھ سکتے ہیں۔ |
||||
|
|
||||
|
Environment variables application **settings** کو سنبھالنے، Python کی **installation** کے حصے کے طور پر وغیرہ کے لیے مفید ہو سکتے ہیں۔ |
||||
|
|
||||
|
## Env Vars بنائیں اور استعمال کریں { #create-and-use-env-vars } |
||||
|
|
||||
|
آپ **shell (terminal)** میں environment variables **بنا** سکتے ہیں اور استعمال کر سکتے ہیں، Python کی ضرورت کے بغیر: |
||||
|
|
||||
|
//// tab | Linux, macOS, Windows Bash |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
// You could create an env var MY_NAME with |
||||
|
$ export MY_NAME="Wade Wilson" |
||||
|
|
||||
|
// Then you could use it with other programs, like |
||||
|
$ echo "Hello $MY_NAME" |
||||
|
|
||||
|
Hello Wade Wilson |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows PowerShell |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
// Create an env var MY_NAME |
||||
|
$ $Env:MY_NAME = "Wade Wilson" |
||||
|
|
||||
|
// Use it with other programs, like |
||||
|
$ echo "Hello $Env:MY_NAME" |
||||
|
|
||||
|
Hello Wade Wilson |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
## Python میں env vars پڑھیں { #read-env-vars-in-python } |
||||
|
|
||||
|
آپ Python سے **باہر**، terminal میں (یا کسی اور طریقے سے) بھی environment variables بنا سکتے ہیں، اور پھر **Python میں انہیں پڑھ** سکتے ہیں۔ |
||||
|
|
||||
|
مثال کے طور پر آپ کے پاس `main.py` فائل ہو سکتی ہے: |
||||
|
|
||||
|
```Python hl_lines="3" |
||||
|
import os |
||||
|
|
||||
|
name = os.getenv("MY_NAME", "World") |
||||
|
print(f"Hello {name} from Python") |
||||
|
``` |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
[`os.getenv()`](https://docs.python.org/3.8/library/os.html#os.getenv) کا دوسرا argument واپس کرنے کے لیے default value ہے۔ |
||||
|
|
||||
|
اگر فراہم نہ کیا جائے تو بطور default یہ `None` ہے، یہاں ہم استعمال کرنے کے لیے default value `"World"` فراہم کر رہے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
پھر آپ اس Python program کو call کر سکتے ہیں: |
||||
|
|
||||
|
//// tab | Linux, macOS, Windows Bash |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
// Here we don't set the env var yet |
||||
|
$ python main.py |
||||
|
|
||||
|
// As we didn't set the env var, we get the default value |
||||
|
|
||||
|
Hello World from Python |
||||
|
|
||||
|
// But if we create an environment variable first |
||||
|
$ export MY_NAME="Wade Wilson" |
||||
|
|
||||
|
// And then call the program again |
||||
|
$ python main.py |
||||
|
|
||||
|
// Now it can read the environment variable |
||||
|
|
||||
|
Hello Wade Wilson from Python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows PowerShell |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
// Here we don't set the env var yet |
||||
|
$ python main.py |
||||
|
|
||||
|
// As we didn't set the env var, we get the default value |
||||
|
|
||||
|
Hello World from Python |
||||
|
|
||||
|
// But if we create an environment variable first |
||||
|
$ $Env:MY_NAME = "Wade Wilson" |
||||
|
|
||||
|
// And then call the program again |
||||
|
$ python main.py |
||||
|
|
||||
|
// Now it can read the environment variable |
||||
|
|
||||
|
Hello Wade Wilson from Python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
چونکہ environment variables code سے باہر سیٹ ہو سکتے ہیں، لیکن code کے ذریعے پڑھے جا سکتے ہیں، اور باقی فائلوں کے ساتھ (`git` میں commit) محفوظ نہیں ہونے چاہئیں، ان کو configurations یا **settings** کے لیے استعمال کرنا عام ہے۔ |
||||
|
|
||||
|
آپ ایک environment variable صرف کسی **خاص program invocation** کے لیے بھی بنا سکتے ہیں، جو صرف اس program کے لیے دستیاب ہو، اور صرف اس کے دورانیے کے لیے۔ |
||||
|
|
||||
|
ایسا کرنے کے لیے، اسے program سے ٹھیک پہلے، اسی لائن پر بنائیں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
// Create an env var MY_NAME in line for this program call |
||||
|
$ MY_NAME="Wade Wilson" python main.py |
||||
|
|
||||
|
// Now it can read the environment variable |
||||
|
|
||||
|
Hello Wade Wilson from Python |
||||
|
|
||||
|
// The env var no longer exists afterwards |
||||
|
$ python main.py |
||||
|
|
||||
|
Hello World from Python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
آپ اس کے بارے میں مزید [The Twelve-Factor App: Config](https://12factor.net/config) پر پڑھ سکتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Types اور Validation { #types-and-validation } |
||||
|
|
||||
|
یہ environment variables صرف **text strings** کو ہی سنبھال سکتے ہیں، کیونکہ وہ Python سے باہر ہیں اور دوسرے programs اور باقی system (اور مختلف operating systems جیسے Linux، Windows، macOS) کے ساتھ compatible ہونی چاہئیں۔ |
||||
|
|
||||
|
اس کا مطلب ہے کہ Python میں environment variable سے پڑھی جانے والی **کوئی بھی value** ایک **`str`** ہوگی، اور کسی مختلف type میں تبدیلی یا کوئی validation code میں کرنا ہوگا۔ |
||||
|
|
||||
|
آپ application **settings** سنبھالنے کے لیے environment variables استعمال کرنے کے بارے میں مزید [Advanced User Guide - Settings and Environment Variables](./advanced/settings.md) میں سیکھیں گے۔ |
||||
|
|
||||
|
## `PATH` Environment Variable { #path-environment-variable } |
||||
|
|
||||
|
ایک **خاص** environment variable ہے جسے **`PATH`** کہتے ہیں جو operating systems (Linux، macOS، Windows) چلانے کے لیے programs تلاش کرنے میں استعمال کرتا ہے۔ |
||||
|
|
||||
|
Variable `PATH` کی value ایک لمبی string ہے جو directories پر مشتمل ہے جو Linux اور macOS پر colon `:` سے اور Windows پر semicolon `;` سے الگ ہوتی ہیں۔ |
||||
|
|
||||
|
مثال کے طور پر، `PATH` environment variable اس طرح نظر آ سکتا ہے: |
||||
|
|
||||
|
//// tab | Linux, macOS |
||||
|
|
||||
|
```plaintext |
||||
|
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin |
||||
|
``` |
||||
|
|
||||
|
اس کا مطلب ہے کہ system کو ان directories میں programs تلاش کرنے چاہئیں: |
||||
|
|
||||
|
* `/usr/local/bin` |
||||
|
* `/usr/bin` |
||||
|
* `/bin` |
||||
|
* `/usr/sbin` |
||||
|
* `/sbin` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows |
||||
|
|
||||
|
```plaintext |
||||
|
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32 |
||||
|
``` |
||||
|
|
||||
|
اس کا مطلب ہے کہ system کو ان directories میں programs تلاش کرنے چاہئیں: |
||||
|
|
||||
|
* `C:\Program Files\Python312\Scripts` |
||||
|
* `C:\Program Files\Python312` |
||||
|
* `C:\Windows\System32` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
جب آپ terminal میں کوئی **command** ٹائپ کرتے ہیں، تو operating system `PATH` environment variable میں درج **ہر directory** میں program **تلاش کرتا ہے**۔ |
||||
|
|
||||
|
مثال کے طور پر، جب آپ terminal میں `python` ٹائپ کرتے ہیں، تو operating system اس فہرست کی **پہلی directory** میں `python` نامی program تلاش کرتا ہے۔ |
||||
|
|
||||
|
اگر مل جائے تو وہ اسے **استعمال کرے گا**۔ ورنہ **دوسری directories** میں تلاش جاری رکھتا ہے۔ |
||||
|
|
||||
|
### Python install کرنا اور `PATH` کو اپڈیٹ کرنا { #installing-python-and-updating-the-path } |
||||
|
|
||||
|
جب آپ Python install کرتے ہیں، تو آپ سے پوچھا جا سکتا ہے کہ کیا آپ `PATH` environment variable کو اپڈیٹ کرنا چاہتے ہیں۔ |
||||
|
|
||||
|
//// tab | Linux, macOS |
||||
|
|
||||
|
فرض کریں آپ Python install کرتے ہیں اور یہ `/opt/custompython/bin` directory میں آتا ہے۔ |
||||
|
|
||||
|
اگر آپ `PATH` environment variable اپڈیٹ کرنے پر ہاں کہیں، تو installer `/opt/custompython/bin` کو `PATH` environment variable میں شامل کر دے گا۔ |
||||
|
|
||||
|
یہ اس طرح نظر آ سکتا ہے: |
||||
|
|
||||
|
```plaintext |
||||
|
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin |
||||
|
``` |
||||
|
|
||||
|
اس طرح، جب آپ terminal میں `python` ٹائپ کریں گے، تو system `/opt/custompython/bin` (آخری directory) میں Python program تلاش کرے گا اور اسے استعمال کرے گا۔ |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows |
||||
|
|
||||
|
فرض کریں آپ Python install کرتے ہیں اور یہ `C:\opt\custompython\bin` directory میں آتا ہے۔ |
||||
|
|
||||
|
اگر آپ `PATH` environment variable اپڈیٹ کرنے پر ہاں کہیں، تو installer `C:\opt\custompython\bin` کو `PATH` environment variable میں شامل کر دے گا۔ |
||||
|
|
||||
|
```plaintext |
||||
|
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin |
||||
|
``` |
||||
|
|
||||
|
اس طرح، جب آپ terminal میں `python` ٹائپ کریں گے، تو system `C:\opt\custompython\bin` (آخری directory) میں Python program تلاش کرے گا اور اسے استعمال کرے گا۔ |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
تو اگر آپ ٹائپ کریں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// tab | Linux, macOS |
||||
|
|
||||
|
System `/opt/custompython/bin` میں `python` program **تلاش** کرے گا اور اسے چلائے گا۔ |
||||
|
|
||||
|
یہ تقریباً اس کے مساوی ہوگا: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ /opt/custompython/bin/python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
//// tab | Windows |
||||
|
|
||||
|
System `C:\opt\custompython\bin\python` میں `python` program **تلاش** کرے گا اور اسے چلائے گا۔ |
||||
|
|
||||
|
یہ تقریباً اس کے مساوی ہوگا: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ C:\opt\custompython\bin\python |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
یہ معلومات [Virtual Environments](virtual-environments.md) کے بارے میں سیکھتے وقت مفید ہوں گی۔ |
||||
|
|
||||
|
## نتیجہ { #conclusion } |
||||
|
|
||||
|
اس کے ساتھ آپ کو اس بات کی بنیادی سمجھ ہونی چاہیے کہ **environment variables** کیا ہیں اور Python میں انہیں کیسے استعمال کرنا ہے۔ |
||||
|
|
||||
|
آپ ان کے بارے میں مزید [Wikipedia for Environment Variable](https://en.wikipedia.org/wiki/Environment_variable) پر بھی پڑھ سکتے ہیں۔ |
||||
|
|
||||
|
بہت سے معاملات میں یہ فوری طور پر واضح نہیں ہوتا کہ environment variables کیسے مفید اور قابل اطلاق ہوں گے۔ لیکن جب آپ development کر رہے ہوتے ہیں تو یہ بہت سے مختلف منظرناموں میں سامنے آتے رہتے ہیں، تو ان کے بارے میں جاننا اچھا ہے۔ |
||||
|
|
||||
|
مثال کے طور پر، اگلے سیکشن [Virtual Environments](virtual-environments.md) میں آپ کو یہ معلومات کی ضرورت ہوگی۔ |
||||
@ -0,0 +1,25 @@ |
|||||
|
# بیرونی لنکس |
||||
|
|
||||
|
**FastAPI** کی ایک شاندار کمیونٹی ہے جو مسلسل بڑھ رہی ہے۔ |
||||
|
|
||||
|
**FastAPI** سے متعلق بہت سے مضامین، مقالات، tools، اور projects ہیں۔ |
||||
|
|
||||
|
آپ آسانی سے search engine یا video platform استعمال کرکے FastAPI سے متعلق بہت سے وسائل تلاش کر سکتے ہیں۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
پہلے، اس صفحے پر بیرونی مضامین کے لنکس درج کیے جاتے تھے۔ |
||||
|
|
||||
|
لیکن اب جب FastAPI تمام زبانوں میں سب سے زیادہ GitHub stars والا backend framework ہے، اور Python میں سب سے زیادہ starred اور استعمال ہونے والا framework ہے، تو اس کے بارے میں لکھے گئے تمام مضامین درج کرنے کی کوشش کرنا اب مناسب نہیں رہا۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## GitHub Repositories |
||||
|
|
||||
|
سب سے زیادہ starred [`fastapi` topic والی GitHub repositories](https://github.com/topics/fastapi): |
||||
|
|
||||
|
{% for repo in topic_repos %} |
||||
|
|
||||
|
<a href={{repo.html_url}} target="_blank">★ {{repo.stars}} - {{repo.name}}</a> by <a href={{repo.owner_html_url}} target="_blank">@{{repo.owner_login}}</a>. |
||||
|
|
||||
|
{% endfor %} |
||||
@ -0,0 +1,128 @@ |
|||||
|
# FastAPI CLI { #fastapi-cli } |
||||
|
|
||||
|
**FastAPI <abbr title="command line interface">CLI</abbr>** ایک command line program ہے جسے آپ اپنی FastAPI app serve کرنے، اپنا FastAPI project منظم کرنے، اور مزید کاموں کے لیے استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
جب آپ FastAPI install کرتے ہیں (مثلاً `pip install "fastapi[standard]"` سے)، تو یہ ایک command line program کے ساتھ آتا ہے جسے آپ terminal میں چلا سکتے ہیں۔ |
||||
|
|
||||
|
اپنی FastAPI app کو development کے لیے چلانے کے لیے، آپ `fastapi dev` command استعمال کر سکتے ہیں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ <font color="#4E9A06">fastapi</font> dev |
||||
|
|
||||
|
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting development server 🚀 |
||||
|
|
||||
|
Searching for package file structure from directories with |
||||
|
<font color="#3465A4">__init__.py</font> files |
||||
|
Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font> |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> module </font></span> 🐍 main.py |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> code </font></span> Importing the FastAPI app object from the module with the |
||||
|
following code: |
||||
|
|
||||
|
<u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u> |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> app </font></span> Using import string: <font color="#3465A4">main:app</font> |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font> |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000/docs</u></font> |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> tip </font></span> Running in development mode, for production use: |
||||
|
<b>fastapi run</b> |
||||
|
|
||||
|
Logs: |
||||
|
|
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Will watch for changes in these directories: |
||||
|
<b>[</b><font color="#4E9A06">'/home/user/code/awesomeapp'</font><b>]</b> |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font> <b>(</b>Press CTRL+C to |
||||
|
quit<b>)</b> |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started reloader process <b>[</b><font color="#34E2E2"><b>383138</b></font><b>]</b> using WatchFiles |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>383153</b></font><b>]</b> |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup. |
||||
|
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete. |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
Production کے لیے آپ `fastapi dev` کی بجائے `fastapi run` استعمال کریں گے۔ 🚀 |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
اندرونی طور پر، **FastAPI CLI** [Uvicorn](https://www.uvicorn.dev) استعمال کرتا ہے، ایک اعلیٰ performance والا، production-ready، ASGI server۔ 😎 |
||||
|
|
||||
|
`fastapi` CLI خودکار طور پر چلانے والی FastAPI app کو detect کرنے کی کوشش کرے گا، یہ فرض کرتے ہوئے کہ یہ `main.py` فائل میں `app` نامی object ہے (یا کچھ دوسرے متبادل)۔ |
||||
|
|
||||
|
لیکن آپ واضح طور پر استعمال کرنے والی app configure کر سکتے ہیں۔ |
||||
|
|
||||
|
## `pyproject.toml` میں app کا `entrypoint` configure کریں { #configure-the-app-entrypoint-in-pyproject-toml } |
||||
|
|
||||
|
آپ `pyproject.toml` فائل میں اپنی app کی جگہ configure کر سکتے ہیں جیسے: |
||||
|
|
||||
|
```toml |
||||
|
[tool.fastapi] |
||||
|
entrypoint = "main:app" |
||||
|
``` |
||||
|
|
||||
|
یہ `entrypoint`، `fastapi` command کو بتائے گا کہ اسے app اس طرح import کرنی چاہیے: |
||||
|
|
||||
|
```python |
||||
|
from main import app |
||||
|
``` |
||||
|
|
||||
|
اگر آپ کا code اس طرح ترتیب دیا گیا ہے: |
||||
|
|
||||
|
``` |
||||
|
. |
||||
|
├── backend |
||||
|
│ ├── main.py |
||||
|
│ ├── __init__.py |
||||
|
``` |
||||
|
|
||||
|
تو آپ `entrypoint` اس طرح سیٹ کریں گے: |
||||
|
|
||||
|
```toml |
||||
|
[tool.fastapi] |
||||
|
entrypoint = "backend.main:app" |
||||
|
``` |
||||
|
|
||||
|
جو اس کے مساوی ہوگا: |
||||
|
|
||||
|
```python |
||||
|
from backend.main import app |
||||
|
``` |
||||
|
|
||||
|
### path کے ساتھ `fastapi dev` { #fastapi-dev-with-path } |
||||
|
|
||||
|
آپ `fastapi dev` command کو فائل کا path بھی دے سکتے ہیں، اور یہ استعمال کرنے والی FastAPI app object کا اندازہ لگائے گا: |
||||
|
|
||||
|
```console |
||||
|
$ fastapi dev main.py |
||||
|
``` |
||||
|
|
||||
|
لیکن آپ کو ہر بار `fastapi` command call کرتے وقت صحیح path یاد رکھنا ہوگا۔ |
||||
|
|
||||
|
اس کے علاوہ، دوسرے tools شاید اسے تلاش نہ کر سکیں، مثلاً [VS Code Extension](editor-support.md) یا [FastAPI Cloud](https://fastapicloud.com)، تو `pyproject.toml` میں `entrypoint` استعمال کرنا تجویز کیا جاتا ہے۔ |
||||
|
|
||||
|
## `fastapi dev` { #fastapi-dev } |
||||
|
|
||||
|
`fastapi dev` چلانے سے development mode شروع ہوتا ہے۔ |
||||
|
|
||||
|
بطور default، **auto-reload** فعال ہوتا ہے، جب آپ اپنے code میں تبدیلیاں کرتے ہیں تو server خودکار طور پر دوبارہ لوڈ ہوتا ہے۔ یہ وسائل کا زیادہ استعمال کرتا ہے اور غیر فعال ہونے کی نسبت کم مستحکم ہو سکتا ہے۔ آپ کو اسے صرف development کے لیے استعمال کرنا چاہیے۔ یہ IP address `127.0.0.1` پر بھی سنتا ہے، جو آپ کی مشین کا خود سے بات چیت کرنے کا IP ہے (`localhost`)۔ |
||||
|
|
||||
|
## `fastapi run` { #fastapi-run } |
||||
|
|
||||
|
`fastapi run` چلانے سے FastAPI production mode میں شروع ہوتا ہے۔ |
||||
|
|
||||
|
بطور default، **auto-reload** غیر فعال ہوتا ہے۔ یہ IP address `0.0.0.0` پر سنتا ہے، یعنی تمام دستیاب IP addresses، اس طرح یہ ہر اس شخص کے لیے عوامی طور پر قابل رسائی ہوگا جو مشین سے بات چیت کر سکتا ہے۔ عام طور پر آپ اسے production میں اسی طرح چلائیں گے، مثلاً container میں۔ |
||||
|
|
||||
|
زیادہ تر معاملات میں آپ کے پاس ایک "termination proxy" ہوگا جو آپ کے لیے HTTPS سنبھالتا ہے، یہ آپ کی application کو deploy کرنے کے طریقے پر منحصر ہے، آپ کا provider شاید یہ آپ کے لیے کرے، یا آپ کو خود سیٹ اپ کرنا ہوگا۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
آپ اس کے بارے میں مزید [deployment documentation](deployment/index.md) میں سیکھ سکتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
@ -0,0 +1,285 @@ |
|||||
|
--- |
||||
|
hide: |
||||
|
- navigation |
||||
|
--- |
||||
|
|
||||
|
# FastAPI کے لوگ |
||||
|
|
||||
|
FastAPI کی ایک حیرت انگیز کمیونٹی ہے جو ہر پس منظر سے لوگوں کا خیرمقدم کرتی ہے۔ |
||||
|
|
||||
|
## بانی |
||||
|
|
||||
|
ارے! 👋 |
||||
|
|
||||
|
یہ میں ہوں: |
||||
|
|
||||
|
<div class="user-list user-list-center"> |
||||
|
{% for user in people.maintainers %} |
||||
|
|
||||
|
<div class="user"><a href="{{ contributors.tiangolo.url }}"><div class="avatar-wrapper"><img src="{{ contributors.tiangolo.avatarUrl }}"/></div><div class="title">@{{ contributors.tiangolo.login }}</div></a> <div class="count">Answers: {{ user.answers }}</div><div class="count">Pull Requests: {{ contributors.tiangolo.count }}</div></div> |
||||
|
{% endfor %} |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
میں **FastAPI** کا بانی ہوں۔ آپ اس کے بارے میں مزید [FastAPI کی مدد کریں - مدد حاصل کریں - مصنف سے جڑیں](help-fastapi.md#connect-with-the-author) میں پڑھ سکتے ہیں۔ |
||||
|
|
||||
|
...لیکن یہاں میں آپ کو کمیونٹی دکھانا چاہتا ہوں۔ |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
**FastAPI** کو کمیونٹی سے بہت زیادہ حمایت ملتی ہے۔ اور میں ان کے تعاون کو نمایاں کرنا چاہتا ہوں۔ |
||||
|
|
||||
|
یہ وہ لوگ ہیں جو: |
||||
|
|
||||
|
* [GitHub میں سوالات کے ساتھ دوسروں کی مدد کرتے ہیں](help-fastapi.md#help-others-with-questions-in-github)۔ |
||||
|
* [Pull Requests بناتے ہیں](help-fastapi.md#create-a-pull-request)۔ |
||||
|
* Pull Requests کا Review کرتے ہیں، [خاص طور پر تراجم کے لیے اہم](contributing.md#translations)۔ |
||||
|
* [Repository منظم](management-tasks.md) کرنے میں مدد کرتے ہیں (ٹیم ممبران)۔ |
||||
|
|
||||
|
یہ سب کام repository کو برقرار رکھنے میں مدد کرتے ہیں۔ |
||||
|
|
||||
|
ان کے لیے تالیاں۔ 👏 🙇 |
||||
|
|
||||
|
## ٹیم |
||||
|
|
||||
|
یہ موجودہ ٹیم ممبران کی فہرست ہے۔ 😎 |
||||
|
|
||||
|
ان کی شمولیت اور اجازتوں کی مختلف سطحیں ہیں، وہ [repository management tasks](./management-tasks.md) انجام دے سکتے ہیں اور مل کر ہم [FastAPI repository کو منظم کرتے ہیں](./management.md)۔ |
||||
|
|
||||
|
<div class="user-list user-list-center"> |
||||
|
|
||||
|
{% for user in members["members"] %} |
||||
|
|
||||
|
<div class="user"><a href="{{ user.url }}"><div class="avatar-wrapper"><img src="{{ user.avatar_url }}"/></div><div class="title">@{{ user.login }}</div></a></div> |
||||
|
|
||||
|
{% endfor %} |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
حالانکہ ٹیم ممبران کے پاس خصوصی کام انجام دینے کی اجازتیں ہیں، [FastAPI کو برقرار رکھنے میں دوسروں کی ہر مدد](./help-fastapi.md#help-maintain-fastapi) کی بہت قدر کی جاتی ہے! 🙇♂️ |
||||
|
|
||||
|
## FastAPI Experts |
||||
|
|
||||
|
یہ وہ صارفین ہیں جو [GitHub میں سوالات کے ساتھ سب سے زیادہ دوسروں کی مدد](help-fastapi.md#help-others-with-questions-in-github) کرتے رہے ہیں۔ 🙇 |
||||
|
|
||||
|
انہوں نے بہت سے دوسروں کی مدد کرکے ثابت کیا ہے کہ وہ **FastAPI Experts** ہیں۔ ✨ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
آپ بھی سرکاری FastAPI Expert بن سکتے ہیں! |
||||
|
|
||||
|
بس [GitHub میں سوالات کے ساتھ دوسروں کی مدد کریں](help-fastapi.md#help-others-with-questions-in-github)۔ 🤓 |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
آپ **FastAPI Experts** یہاں دیکھ سکتے ہیں: |
||||
|
|
||||
|
* [پچھلا مہینہ](#fastapi-experts-last-month) 🤓 |
||||
|
* [3 مہینے](#fastapi-experts-3-months) 😎 |
||||
|
* [6 مہینے](#fastapi-experts-6-months) 🧐 |
||||
|
* [1 سال](#fastapi-experts-1-year) 🧑🔬 |
||||
|
* [**ہمیشہ**](#fastapi-experts-all-time) 🧙 |
||||
|
|
||||
|
### FastAPI Experts - پچھلا مہینہ |
||||
|
|
||||
|
یہ وہ صارفین ہیں جو پچھلے مہینے [GitHub میں سوالات کے ساتھ سب سے زیادہ دوسروں کی مدد](help-fastapi.md#help-others-with-questions-in-github) کرتے رہے ہیں۔ 🤓 |
||||
|
|
||||
|
<div class="user-list user-list-center"> |
||||
|
|
||||
|
{% for user in people.last_month_experts[:10] %} |
||||
|
|
||||
|
{% if user.login not in skip_users %} |
||||
|
|
||||
|
<div class="user"><a href="{{ user.url }}"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Questions replied: {{ user.count }}</div></div> |
||||
|
|
||||
|
{% endif %} |
||||
|
|
||||
|
{% endfor %} |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
### FastAPI Experts - 3 مہینے |
||||
|
|
||||
|
یہ وہ صارفین ہیں جو پچھلے 3 مہینوں میں [GitHub میں سوالات کے ساتھ سب سے زیادہ دوسروں کی مدد](help-fastapi.md#help-others-with-questions-in-github) کرتے رہے ہیں۔ 😎 |
||||
|
|
||||
|
<div class="user-list user-list-center"> |
||||
|
|
||||
|
{% for user in people.three_months_experts[:10] %} |
||||
|
|
||||
|
{% if user.login not in skip_users %} |
||||
|
|
||||
|
<div class="user"><a href="{{ user.url }}"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Questions replied: {{ user.count }}</div></div> |
||||
|
|
||||
|
{% endif %} |
||||
|
|
||||
|
{% endfor %} |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
### FastAPI Experts - 6 مہینے |
||||
|
|
||||
|
یہ وہ صارفین ہیں جو پچھلے 6 مہینوں میں [GitHub میں سوالات کے ساتھ سب سے زیادہ دوسروں کی مدد](help-fastapi.md#help-others-with-questions-in-github) کرتے رہے ہیں۔ 🧐 |
||||
|
|
||||
|
<div class="user-list user-list-center"> |
||||
|
|
||||
|
{% for user in people.six_months_experts[:10] %} |
||||
|
|
||||
|
{% if user.login not in skip_users %} |
||||
|
|
||||
|
<div class="user"><a href="{{ user.url }}"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Questions replied: {{ user.count }}</div></div> |
||||
|
|
||||
|
{% endif %} |
||||
|
|
||||
|
{% endfor %} |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
### FastAPI Experts - 1 سال |
||||
|
|
||||
|
یہ وہ صارفین ہیں جو پچھلے سال [GitHub میں سوالات کے ساتھ سب سے زیادہ دوسروں کی مدد](help-fastapi.md#help-others-with-questions-in-github) کرتے رہے ہیں۔ 🧑🔬 |
||||
|
|
||||
|
<div class="user-list user-list-center"> |
||||
|
|
||||
|
{% for user in people.one_year_experts[:20] %} |
||||
|
|
||||
|
{% if user.login not in skip_users %} |
||||
|
|
||||
|
<div class="user"><a href="{{ user.url }}"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Questions replied: {{ user.count }}</div></div> |
||||
|
|
||||
|
{% endif %} |
||||
|
|
||||
|
{% endfor %} |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
### FastAPI Experts - ہمیشہ |
||||
|
|
||||
|
یہ ہیں ہمیشہ کے **FastAPI Experts**۔ 🤓🤯 |
||||
|
|
||||
|
یہ وہ صارفین ہیں جنہوں نے *ہمیشہ سے* [GitHub میں سوالات کے ساتھ سب سے زیادہ دوسروں کی مدد](help-fastapi.md#help-others-with-questions-in-github) کی ہے۔ 🧙 |
||||
|
|
||||
|
<div class="user-list user-list-center"> |
||||
|
|
||||
|
{% for user in people.experts[:50] %} |
||||
|
|
||||
|
{% if user.login not in skip_users %} |
||||
|
|
||||
|
<div class="user"><a href="{{ user.url }}"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Questions replied: {{ user.count }}</div></div> |
||||
|
|
||||
|
{% endif %} |
||||
|
|
||||
|
{% endfor %} |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
## اعلیٰ شراکت دار |
||||
|
|
||||
|
یہ ہیں **اعلیٰ شراکت دار**۔ 👷 |
||||
|
|
||||
|
ان صارفین نے سب سے زیادہ [Pull Requests بنائی ہیں](help-fastapi.md#create-a-pull-request) جو *merge* ہو چکی ہیں۔ |
||||
|
|
||||
|
انہوں نے source code، documentation وغیرہ میں تعاون کیا ہے۔ 📦 |
||||
|
|
||||
|
<div class="user-list user-list-center"> |
||||
|
|
||||
|
{% for user in (contributors.values() | list)[:50] %} |
||||
|
|
||||
|
{% if user.login not in skip_users %} |
||||
|
|
||||
|
<div class="user"><a href="{{ user.url }}"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Pull Requests: {{ user.count }}</div></div> |
||||
|
|
||||
|
{% endif %} |
||||
|
|
||||
|
{% endfor %} |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
سینکڑوں دوسرے شراکت دار بھی ہیں، آپ انہیں [FastAPI GitHub Contributors page](https://github.com/fastapi/fastapi/graphs/contributors) پر دیکھ سکتے ہیں۔ 👷 |
||||
|
|
||||
|
## اعلیٰ ترجمہ جائزہ کار |
||||
|
|
||||
|
یہ صارفین **اعلیٰ ترجمہ جائزہ کار** ہیں۔ 🕵️ |
||||
|
|
||||
|
ترجمہ جائزہ کاروں کے پاس documentation کے [**تراجم کی منظوری**](contributing.md#translations) دینے کا اختیار ہے۔ ان کے بغیر، کئی دوسری زبانوں میں documentation نہ ہوتی۔ |
||||
|
|
||||
|
<div class="user-list user-list-center"> |
||||
|
{% for user in (translation_reviewers.values() | list)[:50] %} |
||||
|
|
||||
|
{% if user.login not in skip_users %} |
||||
|
|
||||
|
<div class="user"><a href="{{ user.url }}"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Reviews: {{ user.count }}</div></div> |
||||
|
|
||||
|
{% endif %} |
||||
|
|
||||
|
{% endfor %} |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
## سرپرست |
||||
|
|
||||
|
یہ ہیں **سرپرست**۔ 😎 |
||||
|
|
||||
|
وہ **FastAPI** (اور دوسرے) کے ساتھ میرے کام کی حمایت کر رہے ہیں، بنیادی طور پر [GitHub Sponsors](https://github.com/sponsors/tiangolo) کے ذریعے۔ |
||||
|
|
||||
|
{% if sponsors %} |
||||
|
|
||||
|
{% if sponsors.gold %} |
||||
|
|
||||
|
### گولڈ سرپرست |
||||
|
|
||||
|
{% for sponsor in sponsors.gold -%} |
||||
|
<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a> |
||||
|
{% endfor %} |
||||
|
{% endif %} |
||||
|
|
||||
|
{% if sponsors.silver %} |
||||
|
|
||||
|
### سلور سرپرست |
||||
|
|
||||
|
{% for sponsor in sponsors.silver -%} |
||||
|
<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a> |
||||
|
{% endfor %} |
||||
|
{% endif %} |
||||
|
|
||||
|
{% if sponsors.bronze %} |
||||
|
|
||||
|
### برانز سرپرست |
||||
|
|
||||
|
{% for sponsor in sponsors.bronze -%} |
||||
|
<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a> |
||||
|
{% endfor %} |
||||
|
{% endif %} |
||||
|
|
||||
|
{% endif %} |
||||
|
|
||||
|
### انفرادی سرپرست |
||||
|
|
||||
|
{% if github_sponsors %} |
||||
|
{% for group in github_sponsors.sponsors %} |
||||
|
|
||||
|
<div class="user-list user-list-center"> |
||||
|
|
||||
|
{% for user in group %} |
||||
|
{% if user.login not in sponsors_badge.logins %} |
||||
|
|
||||
|
<div class="user"><a href="{{ user.url }}"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a></div> |
||||
|
|
||||
|
{% endif %} |
||||
|
{% endfor %} |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
{% endfor %} |
||||
|
{% endif %} |
||||
|
|
||||
|
## ڈیٹا کے بارے میں - تکنیکی تفصیلات |
||||
|
|
||||
|
اس صفحے کا بنیادی مقصد کمیونٹی کی دوسروں کی مدد کرنے کی کوششوں کو نمایاں کرنا ہے۔ |
||||
|
|
||||
|
خاص طور پر ایسی کوششوں کو شامل کرتے ہوئے جو عام طور پر کم نظر آتی ہیں، اور بہت سے معاملات میں زیادہ محنت طلب ہوتی ہیں، جیسے سوالات میں دوسروں کی مدد کرنا اور تراجم کے ساتھ Pull Requests کا review کرنا۔ |
||||
|
|
||||
|
ڈیٹا ہر مہینے حساب کیا جاتا ہے، آپ [source code یہاں](https://github.com/fastapi/fastapi/blob/master/scripts/) پڑھ سکتے ہیں۔ |
||||
|
|
||||
|
یہاں میں سرپرستوں کے تعاون کو بھی نمایاں کر رہا ہوں۔ |
||||
|
|
||||
|
میں algorithm، سیکشنز، thresholds وغیرہ کو اپڈیٹ کرنے کا حق بھی محفوظ رکھتا ہوں (احتیاطاً 🤷)۔ |
||||
@ -0,0 +1,201 @@ |
|||||
|
# خصوصیات { #features } |
||||
|
|
||||
|
## FastAPI کی خصوصیات { #fastapi-features } |
||||
|
|
||||
|
**FastAPI** آپ کو درج ذیل فراہم کرتا ہے: |
||||
|
|
||||
|
### کھلے معیارات پر مبنی { #based-on-open-standards } |
||||
|
|
||||
|
* API بنانے کے لیے [**OpenAPI**](https://github.com/OAI/OpenAPI-Specification)، جس میں <dfn title="also known as: endpoints, routes">path</dfn> <dfn title="also known as HTTP methods, as POST, GET, PUT, DELETE">operations</dfn>، parameters، request bodies، security وغیرہ کے اعلانات شامل ہیں۔ |
||||
|
* [**JSON Schema**](https://json-schema.org/) کے ساتھ خودکار data model دستاویزات (کیونکہ OpenAPI خود JSON Schema پر مبنی ہے)۔ |
||||
|
* ان معیارات کے گرد ڈیزائن کیا گیا، بغور مطالعے کے بعد۔ بعد میں شامل کی گئی تہہ کے بجائے۔ |
||||
|
* یہ کئی زبانوں میں خودکار **client code generation** کا استعمال بھی ممکن بناتا ہے۔ |
||||
|
|
||||
|
### خودکار دستاویزات { #automatic-docs } |
||||
|
|
||||
|
تعاملی API دستاویزات اور ایکسپلوریشن ویب یوزر انٹرفیسز۔ چونکہ framework OpenAPI پر مبنی ہے، اس لیے کئی اختیارات موجود ہیں، جن میں سے 2 بطور ڈیفالٹ شامل ہیں۔ |
||||
|
|
||||
|
* [**Swagger UI**](https://github.com/swagger-api/swagger-ui)، تعاملی ایکسپلوریشن کے ساتھ، براؤزر سے براہ راست اپنی API کو کال اور ٹیسٹ کریں۔ |
||||
|
|
||||
|
 |
||||
|
|
||||
|
* [**ReDoc**](https://github.com/Rebilly/ReDoc) کے ساتھ متبادل API دستاویزات۔ |
||||
|
|
||||
|
 |
||||
|
|
||||
|
### صرف جدید Python { #just-modern-python } |
||||
|
|
||||
|
یہ سب معیاری **Python type** اعلانات پر مبنی ہے (Pydantic کی بدولت)۔ کوئی نئی syntax سیکھنے کی ضرورت نہیں۔ بس معیاری جدید Python۔ |
||||
|
|
||||
|
اگر آپ کو Python types استعمال کرنے کا 2 منٹ کا جائزہ چاہیے (چاہے آپ FastAPI استعمال نہ کریں)، تو مختصر tutorial دیکھیں: [Python Types](python-types.md)۔ |
||||
|
|
||||
|
آپ types کے ساتھ معیاری Python لکھتے ہیں: |
||||
|
|
||||
|
```Python |
||||
|
from datetime import date |
||||
|
|
||||
|
from pydantic import BaseModel |
||||
|
|
||||
|
# Declare a variable as a str |
||||
|
# and get editor support inside the function |
||||
|
def main(user_id: str): |
||||
|
return user_id |
||||
|
|
||||
|
|
||||
|
# A Pydantic model |
||||
|
class User(BaseModel): |
||||
|
id: int |
||||
|
name: str |
||||
|
joined: date |
||||
|
``` |
||||
|
|
||||
|
جسے پھر اس طرح استعمال کیا جا سکتا ہے: |
||||
|
|
||||
|
```Python |
||||
|
my_user: User = User(id=3, name="John Doe", joined="2018-07-19") |
||||
|
|
||||
|
second_user_data = { |
||||
|
"id": 4, |
||||
|
"name": "Mary", |
||||
|
"joined": "2018-11-30", |
||||
|
} |
||||
|
|
||||
|
my_second_user: User = User(**second_user_data) |
||||
|
``` |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
`**second_user_data` کا مطلب ہے: |
||||
|
|
||||
|
`second_user_data` dict کی keys اور values کو براہ راست key-value arguments کے طور پر پاس کریں، جو اس کے برابر ہے: `User(id=4, name="Mary", joined="2018-11-30")` |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### ایڈیٹر سپورٹ { #editor-support } |
||||
|
|
||||
|
پورا framework آسان اور بدیہی استعمال کے لیے ڈیزائن کیا گیا ہے، تمام فیصلے ترقی شروع کرنے سے پہلے ہی متعدد ایڈیٹرز پر آزمائے گئے تھے، تاکہ بہترین ترقیاتی تجربہ یقینی بنایا جا سکے۔ |
||||
|
|
||||
|
Python ڈویلپر سروے میں، یہ واضح ہے [کہ سب سے زیادہ استعمال ہونے والی خصوصیات میں سے ایک "autocompletion" ہے](https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features)۔ |
||||
|
|
||||
|
پورا **FastAPI** framework اسی کو پورا کرنے کے لیے بنایا گیا ہے۔ Autocompletion ہر جگہ کام کرتی ہے۔ |
||||
|
|
||||
|
آپ کو شاذ و نادر ہی دستاویزات کی طرف واپس آنا پڑے گا۔ |
||||
|
|
||||
|
یہاں آپ کا ایڈیٹر آپ کی مدد کیسے کر سکتا ہے: |
||||
|
|
||||
|
* [Visual Studio Code](https://code.visualstudio.com/) میں: |
||||
|
|
||||
|
 |
||||
|
|
||||
|
* [PyCharm](https://www.jetbrains.com/pycharm/) میں: |
||||
|
|
||||
|
 |
||||
|
|
||||
|
آپ کو ایسے code میں بھی completion ملے گی جو آپ پہلے ناممکن سمجھتے تھے۔ مثال کے طور پر، request سے آنے والے JSON body (جو nested ہو سکتا تھا) کے اندر `price` key۔ |
||||
|
|
||||
|
غلط key نام ٹائپ کرنا، دستاویزات میں آگے پیچھے جانا، یا اوپر نیچے سکرول کرنا کہ آخرکار آپ نے `username` استعمال کیا یا `user_name`، اب ایسا نہیں ہوگا۔ |
||||
|
|
||||
|
### مختصر { #short } |
||||
|
|
||||
|
ہر چیز کے لیے سمجھدار **defaults** ہیں، ہر جگہ اختیاری ترتیبات کے ساتھ۔ تمام parameters کو آپ کی ضرورت کے مطابق ایڈجسٹ کیا جا سکتا ہے اور آپ جو API چاہیں اس کی تعریف کر سکتے ہیں۔ |
||||
|
|
||||
|
لیکن بطور ڈیفالٹ، سب کچھ **"بس کام کرتا ہے"**۔ |
||||
|
|
||||
|
### توثیق { #validation } |
||||
|
|
||||
|
* زیادہ تر (یا تمام؟) Python **data types** کے لیے توثیق، بشمول: |
||||
|
* JSON objects (`dict`)۔ |
||||
|
* JSON array (`list`) آئٹم types کی تعریف کے ساتھ۔ |
||||
|
* String (`str`) فیلڈز، کم از کم اور زیادہ سے زیادہ طوالت کی تعریف کے ساتھ۔ |
||||
|
* Numbers (`int`, `float`) کم از کم اور زیادہ سے زیادہ اقدار کے ساتھ، وغیرہ۔ |
||||
|
|
||||
|
* مزید غیر معمولی types کے لیے توثیق، جیسے: |
||||
|
* URL۔ |
||||
|
* Email۔ |
||||
|
* UUID۔ |
||||
|
* ...اور دیگر۔ |
||||
|
|
||||
|
تمام توثیق معروف اور مضبوط **Pydantic** کے ذریعے ہینڈل ہوتی ہے۔ |
||||
|
|
||||
|
### سیکیورٹی اور تصدیق { #security-and-authentication } |
||||
|
|
||||
|
سیکیورٹی اور تصدیق مربوط ہے۔ ڈیٹابیسز یا data models کے ساتھ کسی سمجھوتے کے بغیر۔ |
||||
|
|
||||
|
OpenAPI میں بیان کردہ تمام security schemes، بشمول: |
||||
|
|
||||
|
* HTTP Basic۔ |
||||
|
* **OAuth2** (بشمول **JWT tokens**)۔ [OAuth2 with JWT](tutorial/security/oauth2-jwt.md) کا tutorial دیکھیں۔ |
||||
|
* API keys بذریعہ: |
||||
|
* Headers۔ |
||||
|
* Query parameters۔ |
||||
|
* Cookies، وغیرہ۔ |
||||
|
|
||||
|
نیز Starlette کی تمام security خصوصیات (بشمول **session cookies**)۔ |
||||
|
|
||||
|
سب کچھ دوبارہ قابل استعمال ٹولز اور اجزاء کے طور پر بنایا گیا ہے جو آپ کے سسٹمز، data stores، relational اور NoSQL ڈیٹابیسز وغیرہ کے ساتھ آسانی سے مربوط ہو سکتے ہیں۔ |
||||
|
|
||||
|
### Dependency Injection { #dependency-injection } |
||||
|
|
||||
|
FastAPI میں انتہائی آسان لیکن انتہائی طاقتور <dfn title='also known as "components", "resources", "services", "providers"'><strong>Dependency Injection</strong></dfn> سسٹم شامل ہے۔ |
||||
|
|
||||
|
* Dependencies کی بھی dependencies ہو سکتی ہیں، جو ایک درجہ بندی یا **dependencies کا "graph"** بناتی ہیں۔ |
||||
|
* سب کچھ framework کے ذریعے **خودکار طور پر ہینڈل** ہوتا ہے۔ |
||||
|
* تمام dependencies requests سے ڈیٹا مانگ سکتی ہیں اور **path operation** کی حدود اور خودکار دستاویزات کو **بہتر** بنا سکتی ہیں۔ |
||||
|
* dependencies میں بیان کردہ *path operation* parameters کے لیے بھی **خودکار توثیق**۔ |
||||
|
* پیچیدہ user authentication سسٹمز، **database connections** وغیرہ کی سپورٹ۔ |
||||
|
* ڈیٹابیسز، frontends وغیرہ کے ساتھ **کوئی سمجھوتا نہیں**۔ لیکن ان سب کے ساتھ آسان انضمام۔ |
||||
|
|
||||
|
### لامحدود "plug-ins" { #unlimited-plug-ins } |
||||
|
|
||||
|
یا دوسرے لفظوں میں، ان کی کوئی ضرورت نہیں، جو code چاہیے import کریں اور استعمال کریں۔ |
||||
|
|
||||
|
کوئی بھی انضمام اتنا سادہ بنایا گیا ہے (dependencies کے ساتھ) کہ آپ اپنی ایپلیکیشن کے لیے 2 لائنوں کے code میں ایک "plug-in" بنا سکتے ہیں، وہی ساخت اور syntax استعمال کرتے ہوئے جو آپ کی *path operations* کے لیے استعمال ہوتی ہے۔ |
||||
|
|
||||
|
### آزمایا ہوا { #tested } |
||||
|
|
||||
|
* 100% <dfn title="The amount of code that is automatically tested">test coverage</dfn>۔ |
||||
|
* 100% <dfn title="Python type annotations, with this your editor and external tools can give you better support">type annotated</dfn> code base۔ |
||||
|
* پروڈکشن ایپلیکیشنز میں استعمال ہو رہا ہے۔ |
||||
|
|
||||
|
## Starlette کی خصوصیات { #starlette-features } |
||||
|
|
||||
|
**FastAPI** مکمل طور پر [**Starlette**](https://www.starlette.dev/) کے ساتھ ہم آہنگ (اور اس پر مبنی) ہے۔ لہٰذا، آپ کا کوئی بھی اضافی Starlette code بھی کام کرے گا۔ |
||||
|
|
||||
|
`FastAPI` دراصل `Starlette` کی ایک sub-class ہے۔ لہٰذا، اگر آپ پہلے سے Starlette جانتے ہیں یا استعمال کرتے ہیں، تو زیادہ تر فعالیت اسی طرح کام کرے گی۔ |
||||
|
|
||||
|
**FastAPI** کے ساتھ آپ کو **Starlette** کی تمام خصوصیات ملتی ہیں (کیونکہ FastAPI بنیادی طور پر Starlette کا بہتر ورژن ہے): |
||||
|
|
||||
|
* سنجیدگی سے متاثر کن کارکردگی۔ یہ [دستیاب تیز ترین Python frameworks میں سے ایک ہے، **NodeJS** اور **Go** کے برابر](https://github.com/encode/starlette#performance)۔ |
||||
|
* **WebSocket** سپورٹ۔ |
||||
|
* In-process background tasks۔ |
||||
|
* Startup اور shutdown events۔ |
||||
|
* HTTPX پر مبنی test client۔ |
||||
|
* **CORS**، GZip، Static Files، Streaming responses۔ |
||||
|
* **Session اور Cookie** سپورٹ۔ |
||||
|
* 100% test coverage۔ |
||||
|
* 100% type annotated codebase۔ |
||||
|
|
||||
|
## Pydantic کی خصوصیات { #pydantic-features } |
||||
|
|
||||
|
**FastAPI** مکمل طور پر [**Pydantic**](https://docs.pydantic.dev/) کے ساتھ ہم آہنگ (اور اس پر مبنی) ہے۔ لہٰذا، آپ کا کوئی بھی اضافی Pydantic code بھی کام کرے گا۔ |
||||
|
|
||||
|
بشمول Pydantic پر مبنی بیرونی لائبریریاں، جیسے ڈیٹابیسز کے لیے <abbr title="Object-Relational Mapper">ORM</abbr>s، <abbr title="Object-Document Mapper">ODM</abbr>s۔ |
||||
|
|
||||
|
اس کا مطلب یہ بھی ہے کہ بہت سے معاملات میں آپ request سے ملنے والی وہی object **براہ راست ڈیٹابیس کو** بھیج سکتے ہیں، کیونکہ ہر چیز خودکار طور پر توثیق شدہ ہوتی ہے۔ |
||||
|
|
||||
|
یہی بات دوسری طرف بھی لاگو ہوتی ہے، بہت سے معاملات میں آپ ڈیٹابیس سے ملنے والی object **براہ راست client کو** بھیج سکتے ہیں۔ |
||||
|
|
||||
|
**FastAPI** کے ساتھ آپ کو **Pydantic** کی تمام خصوصیات ملتی ہیں (کیونکہ FastAPI تمام data handling کے لیے Pydantic پر مبنی ہے): |
||||
|
|
||||
|
* **کوئی الجھن نہیں**: |
||||
|
* سیکھنے کے لیے کوئی نئی schema definition مائیکرو زبان نہیں۔ |
||||
|
* اگر آپ Python types جانتے ہیں تو آپ Pydantic استعمال کرنا جانتے ہیں۔ |
||||
|
* آپ کے **<abbr title="Integrated Development Environment: similar to a code editor">IDE</abbr>/<dfn title="A program that checks for code errors">linter</dfn>/دماغ** کے ساتھ اچھی طرح کام کرتا ہے: |
||||
|
* کیونکہ pydantic data structures صرف آپ کی بیان کردہ classes کی instances ہیں؛ auto-completion، linting، mypy اور آپ کی بصیرت سب آپ کے توثیق شدہ ڈیٹا کے ساتھ صحیح طریقے سے کام کریں گے۔ |
||||
|
* **پیچیدہ ساختوں** کی توثیق کریں: |
||||
|
* درجہ بند Pydantic models، Python `typing` کی `List` اور `Dict` وغیرہ کا استعمال۔ |
||||
|
* اور validators پیچیدہ data schemas کو واضح اور آسانی سے بیان، جانچ اور JSON Schema کے طور پر دستاویز کرنے کی اجازت دیتے ہیں۔ |
||||
|
* آپ کے پاس گہرائی سے **nested JSON** objects ہو سکتے ہیں اور ان سب کی توثیق اور تشریح ہو سکتی ہے۔ |
||||
|
* **قابل توسیع**: |
||||
|
* Pydantic حسب ضرورت data types بیان کرنے کی اجازت دیتا ہے یا آپ validator decorator سے مزین model پر methods کے ساتھ توثیق بڑھا سکتے ہیں۔ |
||||
|
* 100% test coverage۔ |
||||
@ -0,0 +1,256 @@ |
|||||
|
# FastAPI کی مدد کریں - مدد حاصل کریں { #help-fastapi-get-help } |
||||
|
|
||||
|
کیا آپ **FastAPI** پسند کرتے ہیں؟ |
||||
|
|
||||
|
کیا آپ FastAPI، دوسرے صارفین، اور مصنف کی مدد کرنا چاہیں گے؟ |
||||
|
|
||||
|
یا کیا آپ **FastAPI** کے ساتھ مدد حاصل کرنا چاہیں گے؟ |
||||
|
|
||||
|
مدد کرنے کے بہت آسان طریقے ہیں (کئی میں صرف ایک یا دو کلکس شامل ہیں)۔ |
||||
|
|
||||
|
اور مدد حاصل کرنے کے بھی کئی طریقے ہیں۔ |
||||
|
|
||||
|
## Newsletter سبسکرائب کریں { #subscribe-to-the-newsletter } |
||||
|
|
||||
|
آپ (کبھی کبھار آنے والے) [**FastAPI and friends** newsletter](newsletter.md) کو سبسکرائب کر سکتے ہیں تاکہ ان چیزوں سے باخبر رہیں: |
||||
|
|
||||
|
* FastAPI اور دوستوں کے بارے میں خبریں 🚀 |
||||
|
* گائیڈز 📝 |
||||
|
* Features ✨ |
||||
|
* Breaking changes 🚨 |
||||
|
* مشورے اور ٹرکس ✅ |
||||
|
|
||||
|
## X (Twitter) پر FastAPI کو follow کریں { #follow-fastapi-on-x-twitter } |
||||
|
|
||||
|
[**X (Twitter)** پر @fastapi کو follow کریں](https://x.com/fastapi) تاکہ **FastAPI** کے بارے میں تازہ ترین خبریں حاصل کریں۔ 🐦 |
||||
|
|
||||
|
## GitHub پر **FastAPI** کو Star دیں { #star-fastapi-in-github } |
||||
|
|
||||
|
آپ GitHub پر FastAPI کو "star" دے سکتے ہیں (اوپر دائیں جانب star بٹن پر کلک کرکے): [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi)۔ ⭐️ |
||||
|
|
||||
|
Star دینے سے، دوسرے صارفین اسے آسانی سے تلاش کر سکیں گے اور دیکھ سکیں گے کہ یہ پہلے سے دوسروں کے لیے مفید رہا ہے۔ |
||||
|
|
||||
|
## GitHub repository کو releases کے لیے watch کریں { #watch-the-github-repository-for-releases } |
||||
|
|
||||
|
آپ GitHub پر FastAPI کو "watch" کر سکتے ہیں (اوپر دائیں جانب "watch" بٹن پر کلک کرکے): [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi)۔ 👀 |
||||
|
|
||||
|
وہاں آپ "Releases only" منتخب کر سکتے ہیں۔ |
||||
|
|
||||
|
ایسا کرنے سے، جب بھی **FastAPI** کی نئی release (نیا ورژن) آئے گی bug fixes اور نئی features کے ساتھ، آپ کو (اپنی email میں) notifications ملیں گی۔ |
||||
|
|
||||
|
## مصنف سے جڑیں { #connect-with-the-author } |
||||
|
|
||||
|
آپ [مجھ سے (Sebastián Ramírez / `tiangolo`)](https://tiangolo.com)، مصنف، سے رابطہ کر سکتے ہیں۔ |
||||
|
|
||||
|
آپ یہ کر سکتے ہیں: |
||||
|
|
||||
|
* [**GitHub** پر مجھے follow کریں](https://github.com/tiangolo)۔ |
||||
|
* میرے بنائے ہوئے دوسرے Open Source projects دیکھیں جو آپ کی مدد کر سکتے ہیں۔ |
||||
|
* مجھے follow کریں تاکہ جب میں نیا Open Source project بناؤں تو آپ کو معلوم ہو۔ |
||||
|
* [**X (Twitter)** پر مجھے follow کریں](https://x.com/tiangolo) یا [Mastodon](https://fosstodon.org/@tiangolo) پر۔ |
||||
|
* مجھے بتائیں کہ آپ FastAPI کیسے استعمال کرتے ہیں (مجھے یہ سن کر خوشی ہوتی ہے)۔ |
||||
|
* جب میں اعلانات کروں یا نئے tools جاری کروں تو سنیں۔ |
||||
|
* آپ [X (Twitter) پر @fastapi کو بھی follow](https://x.com/fastapi) کر سکتے ہیں (ایک الگ اکاؤنٹ)۔ |
||||
|
* [**LinkedIn** پر مجھے follow کریں](https://www.linkedin.com/in/tiangolo/)۔ |
||||
|
* جب میں اعلانات کروں یا نئے tools جاری کروں تو سنیں (حالانکہ میں X (Twitter) زیادہ استعمال کرتا ہوں 🤷♂)۔ |
||||
|
* [**Dev.to**](https://dev.to/tiangolo) یا [**Medium**](https://medium.com/@tiangolo) پر میری تحریریں پڑھیں (یا مجھے follow کریں)۔ |
||||
|
* دوسرے آئیڈیاز، مضامین پڑھیں، اور میرے بنائے ہوئے tools کے بارے میں پڑھیں۔ |
||||
|
* مجھے follow کریں تاکہ جب میں کچھ نیا شائع کروں تو پڑھ سکیں۔ |
||||
|
|
||||
|
## **FastAPI** کے بارے میں Tweet کریں { #tweet-about-fastapi } |
||||
|
|
||||
|
[**FastAPI** کے بارے میں Tweet کریں](https://x.com/compose/tweet?text=I'm loving @fastapi because... https://github.com/fastapi/fastapi) اور مجھے اور دوسروں کو بتائیں کہ آپ اسے کیوں پسند کرتے ہیں۔ 🎉 |
||||
|
|
||||
|
مجھے یہ سننا پسند ہے کہ **FastAPI** کیسے استعمال ہو رہا ہے، آپ نے اس میں کیا پسند کیا ہے، کس project/company میں آپ اسے استعمال کر رہے ہیں، وغیرہ۔ |
||||
|
|
||||
|
## FastAPI کے لیے ووٹ دیں { #vote-for-fastapi } |
||||
|
|
||||
|
* [Slant پر **FastAPI** کے لیے ووٹ دیں](https://www.slant.co/options/34241/~fastapi-review)۔ |
||||
|
* [AlternativeTo پر **FastAPI** کے لیے ووٹ دیں](https://alternativeto.net/software/fastapi/about/)۔ |
||||
|
* [StackShare پر کہیں کہ آپ **FastAPI** استعمال کرتے ہیں](https://stackshare.io/pypi-fastapi)۔ |
||||
|
|
||||
|
## GitHub میں سوالات کے ساتھ دوسروں کی مدد کریں { #help-others-with-questions-in-github } |
||||
|
|
||||
|
آپ دوسروں کے سوالات میں مدد کرنے کی کوشش کر سکتے ہیں: |
||||
|
|
||||
|
* [GitHub Discussions](https://github.com/fastapi/fastapi/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered) |
||||
|
* [GitHub Issues](https://github.com/fastapi/fastapi/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Aquestion+-label%3Aanswered+) |
||||
|
|
||||
|
بہت سے معاملات میں آپ شاید پہلے سے ان سوالات کا جواب جانتے ہوں۔ 🤓 |
||||
|
|
||||
|
اگر آپ بہت سے لوگوں کے سوالات میں مدد کر رہے ہیں، تو آپ ایک سرکاری [FastAPI Expert](fastapi-people.md#fastapi-experts) بن جائیں گے۔ 🎉 |
||||
|
|
||||
|
بس یاد رکھیں، سب سے اہم بات یہ ہے: مہربان ہونے کی کوشش کریں۔ لوگ اپنی پریشانیوں کے ساتھ آتے ہیں اور بہت سے معاملات میں بہترین طریقے سے نہیں پوچھتے، لیکن پوری کوشش کریں کہ مہربان رہیں۔ 🤗 |
||||
|
|
||||
|
**FastAPI** کمیونٹی کا مقصد مہربان اور خوش آمدید ہونا ہے۔ ساتھ ہی، دوسروں کے ساتھ غنڈہ گردی یا بے ادبی برداشت نہ کریں۔ ہمیں ایک دوسرے کا خیال رکھنا ہے۔ |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
یہاں دوسروں کے سوالات میں مدد کرنے کا طریقہ ہے (discussions یا issues میں): |
||||
|
|
||||
|
### سوال سمجھیں { #understand-the-question } |
||||
|
|
||||
|
* چیک کریں کہ کیا آپ سمجھ سکتے ہیں کہ پوچھنے والے شخص کا **مقصد** اور use case کیا ہے۔ |
||||
|
|
||||
|
* پھر چیک کریں کہ کیا سوال (اکثریت سوالات ہوتے ہیں) **واضح** ہے۔ |
||||
|
|
||||
|
* بہت سے معاملات میں پوچھا گیا سوال صارف کے تصور کردہ حل کے بارے میں ہوتا ہے، لیکن اس کا **بہتر** حل ہو سکتا ہے۔ اگر آپ مسئلہ اور use case بہتر سمجھ سکیں، تو آپ بہتر **متبادل حل** تجویز کر سکتے ہیں۔ |
||||
|
|
||||
|
* اگر آپ سوال نہیں سمجھ سکتے، تو مزید **تفصیلات** مانگیں۔ |
||||
|
|
||||
|
### مسئلے کو دوبارہ پیدا کریں { #reproduce-the-problem } |
||||
|
|
||||
|
زیادہ تر معاملات اور سوالات میں شخص کے **اصل code** سے متعلق کوئی بات ہوتی ہے۔ |
||||
|
|
||||
|
بہت سے معاملات میں وہ صرف code کا ایک ٹکڑا کاپی کریں گے، لیکن **مسئلہ دوبارہ پیدا** کرنے کے لیے یہ کافی نہیں ہوتا۔ |
||||
|
|
||||
|
* آپ ان سے [کم سے کم، دوبارہ پیدا کرنے والی مثال](https://stackoverflow.com/help/minimal-reproducible-example) فراہم کرنے کو کہہ سکتے ہیں، جسے آپ **copy-paste** کرکے مقامی طور پر چلا سکیں تاکہ وہی error یا رویہ دیکھ سکیں جو وہ دیکھ رہے ہیں، یا ان کا use case بہتر سمجھ سکیں۔ |
||||
|
|
||||
|
* اگر آپ بہت سخی محسوس کر رہے ہیں، تو آپ مسئلے کی تفصیل کی بنیاد پر خود ایسی **مثال بنانے** کی کوشش کر سکتے ہیں۔ بس یاد رکھیں کہ اس میں بہت وقت لگ سکتا ہے اور بہتر ہو سکتا ہے کہ پہلے انہیں مسئلہ واضح کرنے کو کہیں۔ |
||||
|
|
||||
|
### حل تجویز کریں { #suggest-solutions } |
||||
|
|
||||
|
* سوال سمجھنے کے بعد، آپ انہیں ممکنہ **جواب** دے سکتے ہیں۔ |
||||
|
|
||||
|
* بہت سے معاملات میں، ان کے **بنیادی مسئلے یا use case** کو سمجھنا بہتر ہے، کیونکہ اسے حل کرنے کا ان کی کوشش سے بہتر طریقہ ہو سکتا ہے۔ |
||||
|
|
||||
|
### بند کرنے کو کہیں { #ask-to-close } |
||||
|
|
||||
|
اگر وہ جواب دیں، تو اچھا امکان ہے کہ آپ نے ان کا مسئلہ حل کر دیا ہے، مبارک ہو، **آپ ہیرو ہیں**! 🦸 |
||||
|
|
||||
|
* اب، اگر اس سے ان کا مسئلہ حل ہو گیا، تو آپ ان سے کہہ سکتے ہیں: |
||||
|
|
||||
|
* GitHub Discussions میں: تبصرے کو **جواب** کے طور پر نشان زد کریں۔ |
||||
|
* GitHub Issues میں: issue **بند** کریں۔ |
||||
|
|
||||
|
## GitHub repository کو Watch کریں { #watch-the-github-repository } |
||||
|
|
||||
|
آپ GitHub پر FastAPI کو "watch" کر سکتے ہیں (اوپر دائیں جانب "watch" بٹن پر کلک کرکے): [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi)۔ 👀 |
||||
|
|
||||
|
اگر آپ "Releases only" کی بجائے "Watching" منتخب کرتے ہیں تو جب کوئی نیا issue یا سوال بنائے تو آپ کو notifications ملیں گی۔ آپ یہ بھی بتا سکتے ہیں کہ آپ صرف نئے issues، یا discussions، یا PRs وغیرہ کے بارے میں مطلع ہونا چاہتے ہیں۔ |
||||
|
|
||||
|
پھر آپ ان سوالات کو حل کرنے میں مدد کرنے کی کوشش کر سکتے ہیں۔ |
||||
|
|
||||
|
## سوالات پوچھیں { #ask-questions } |
||||
|
|
||||
|
آپ GitHub repository میں [نیا سوال بنا سکتے ہیں](https://github.com/fastapi/fastapi/discussions/new?category=questions)، مثال کے طور پر: |
||||
|
|
||||
|
* کوئی **سوال** پوچھنے یا **مسئلے** کے بارے میں پوچھنے کے لیے۔ |
||||
|
* نئی **feature** تجویز کرنے کے لیے۔ |
||||
|
|
||||
|
**نوٹ**: اگر آپ ایسا کریں، تو میں آپ سے یہ بھی کہوں گا کہ دوسروں کی بھی مدد کریں۔ 😉 |
||||
|
|
||||
|
## Pull Requests کا Review کریں { #review-pull-requests } |
||||
|
|
||||
|
آپ دوسروں کی pull requests کا review کرنے میں میری مدد کر سکتے ہیں۔ |
||||
|
|
||||
|
دوبارہ، براہ کرم مہربان ہونے کی پوری کوشش کریں۔ 🤗 |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
Pull request کا review کرتے وقت ان باتوں کا خیال رکھیں: |
||||
|
|
||||
|
### مسئلہ سمجھیں { #understand-the-problem } |
||||
|
|
||||
|
* پہلے، یقینی بنائیں کہ آپ وہ **مسئلہ سمجھتے ہیں** جسے pull request حل کرنے کی کوشش کر رہا ہے۔ اس پر GitHub Discussion یا issue میں طویل بحث ہو سکتی ہے۔ |
||||
|
|
||||
|
* اس بات کا بھی اچھا امکان ہے کہ pull request دراصل ضروری نہ ہو کیونکہ مسئلہ **مختلف طریقے** سے حل ہو سکتا ہے۔ پھر آپ اس کے بارے میں تجویز یا سوال کر سکتے ہیں۔ |
||||
|
|
||||
|
### اسلوب کی فکر نہ کریں { #dont-worry-about-style } |
||||
|
|
||||
|
* Commit message styles جیسی چیزوں کی زیادہ فکر نہ کریں، میں squash اور merge کروں گا commit کو دستی طور پر customize کرتے ہوئے۔ |
||||
|
|
||||
|
* اسلوب کے قوانین کی بھی فکر نہ کریں، اسے چیک کرنے والے خودکار tools پہلے سے موجود ہیں۔ |
||||
|
|
||||
|
اور اگر کوئی اور اسلوب یا مطابقت کی ضرورت ہو، تو میں براہ راست مانگوں گا، یا ضروری تبدیلیوں کے ساتھ اوپر commits شامل کروں گا۔ |
||||
|
|
||||
|
### Code چیک کریں { #check-the-code } |
||||
|
|
||||
|
* Code چیک کریں اور پڑھیں، دیکھیں کہ کیا یہ سمجھ آتا ہے، **مقامی طور پر چلائیں** اور دیکھیں کہ کیا یہ واقعی مسئلہ حل کرتا ہے۔ |
||||
|
|
||||
|
* پھر **تبصرہ** کریں کہ آپ نے ایسا کیا، اس طرح مجھے معلوم ہوگا کہ آپ نے واقعی چیک کیا ہے۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
بدقسمتی سے، میں صرف ان PRs پر بھروسہ نہیں کر سکتا جن میں صرف کئی approvals ہوں۔ |
||||
|
|
||||
|
کئی بار ایسا ہوا ہے کہ 3، 5 یا زیادہ approvals والے PRs ہوتے ہیں، شاید اس لیے کہ تفصیل دلکش ہوتی ہے، لیکن جب میں PRs چیک کرتا ہوں تو وہ دراصل ٹوٹے ہوئے ہوتے ہیں، ان میں bug ہوتا ہے، یا وہ اس مسئلے کو حل نہیں کرتے جس کا دعویٰ کرتے ہیں۔ 😅 |
||||
|
|
||||
|
تو واقعی یہ اہم ہے کہ آپ دراصل code پڑھیں اور چلائیں، اور تبصروں میں بتائیں کہ آپ نے ایسا کیا۔ 🤓 |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
* اگر PR کو آسان بنایا جا سکے، تو آپ اس کے لیے کہہ سکتے ہیں، لیکن زیادہ باریک بین ہونے کی ضرورت نہیں، بہت سے ذاتی نقطہ نظر ہو سکتے ہیں (اور میرا اپنا بھی ہوگا 🙈)، تو بنیادی چیزوں پر توجہ مرکوز کرنا بہتر ہے۔ |
||||
|
|
||||
|
### Tests { #tests } |
||||
|
|
||||
|
* مجھے چیک کرنے میں مدد کریں کہ PR میں **tests** ہیں۔ |
||||
|
|
||||
|
* چیک کریں کہ PR سے **پہلے** tests **fail** ہوتے ہیں۔ 🚨 |
||||
|
|
||||
|
* پھر چیک کریں کہ PR کے **بعد** tests **pass** ہوتے ہیں۔ ✅ |
||||
|
|
||||
|
* بہت سے PRs میں tests نہیں ہوتے، آپ انہیں tests شامل کرنے کی **یاد دہانی** کرا سکتے ہیں، یا خود کچھ tests **تجویز** بھی کر سکتے ہیں۔ یہ ان چیزوں میں سے ایک ہے جو سب سے زیادہ وقت لیتی ہے اور آپ اس میں بہت مدد کر سکتے ہیں۔ |
||||
|
|
||||
|
* پھر تبصرہ کریں کہ آپ نے کیا ٹیسٹ کیا، اس طرح مجھے معلوم ہوگا کہ آپ نے چیک کیا۔ 🤓 |
||||
|
|
||||
|
## Pull Request بنائیں { #create-a-pull-request } |
||||
|
|
||||
|
آپ Pull Requests کے ذریعے source code میں [تعاون](contributing.md) کر سکتے ہیں، مثال کے طور پر: |
||||
|
|
||||
|
* documentation میں ملنے والی غلطی درست کرنے کے لیے۔ |
||||
|
* اپنا بنایا یا پایا ہوا FastAPI سے متعلق مضمون، ویڈیو، یا podcast شیئر کرنے کے لیے [اس فائل میں ترمیم کرکے](https://github.com/fastapi/fastapi/edit/master/docs/en/data/external_links.yml)۔ |
||||
|
* یقینی بنائیں کہ آپ اپنا link متعلقہ سیکشن کے شروع میں شامل کریں۔ |
||||
|
* اپنی زبان میں [documentation کا ترجمہ](contributing.md#translations) کرنے میں مدد کے لیے۔ |
||||
|
* آپ دوسروں کے بنائے ہوئے تراجم کا review کرنے میں بھی مدد کر سکتے ہیں۔ |
||||
|
* Documentation کے نئے سیکشنز تجویز کرنے کے لیے۔ |
||||
|
* کسی موجودہ issue/bug کو ٹھیک کرنے کے لیے۔ |
||||
|
* Tests شامل کرنا یقینی بنائیں۔ |
||||
|
* نئی feature شامل کرنے کے لیے۔ |
||||
|
* Tests شامل کرنا یقینی بنائیں۔ |
||||
|
* اگر متعلقہ ہو تو documentation شامل کرنا یقینی بنائیں۔ |
||||
|
|
||||
|
## FastAPI کو برقرار رکھنے میں مدد کریں { #help-maintain-fastapi } |
||||
|
|
||||
|
**FastAPI** کو برقرار رکھنے میں میری مدد کریں! 🤓 |
||||
|
|
||||
|
بہت سارا کام ہے، اور اس میں سے زیادہ تر **آپ** کر سکتے ہیں۔ |
||||
|
|
||||
|
بنیادی کام جو آپ ابھی کر سکتے ہیں: |
||||
|
|
||||
|
* [GitHub میں سوالات کے ساتھ دوسروں کی مدد کریں](#help-others-with-questions-in-github) (اوپر سیکشن دیکھیں)۔ |
||||
|
* [Pull Requests کا Review کریں](#review-pull-requests) (اوپر سیکشن دیکھیں)۔ |
||||
|
|
||||
|
یہ دو کام وہ ہیں جو **سب سے زیادہ وقت لیتے ہیں**۔ یہ FastAPI کو برقرار رکھنے کا بنیادی کام ہے۔ |
||||
|
|
||||
|
اگر آپ اس میں میری مدد کر سکتے ہیں، تو **آپ FastAPI کو برقرار رکھنے میں میری مدد کر رہے ہیں** اور یقینی بنا رہے ہیں کہ یہ **تیزی سے اور بہتر طریقے سے آگے بڑھتا رہے**۔ 🚀 |
||||
|
|
||||
|
## چیٹ میں شامل ہوں { #join-the-chat } |
||||
|
|
||||
|
👥 [Discord چیٹ server](https://discord.gg/VQjSZaeJmf) 👥 میں شامل ہوں اور FastAPI کمیونٹی میں دوسروں کے ساتھ بات چیت کریں۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
سوالات کے لیے، انہیں [GitHub Discussions](https://github.com/fastapi/fastapi/discussions/new?category=questions) میں پوچھیں، وہاں [FastAPI Experts](fastapi-people.md#fastapi-experts) سے مدد ملنے کا بہت بہتر امکان ہے۔ |
||||
|
|
||||
|
چیٹ صرف دوسری عمومی بات چیت کے لیے استعمال کریں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### سوالات کے لیے چیٹ استعمال نہ کریں { #dont-use-the-chat-for-questions } |
||||
|
|
||||
|
یاد رکھیں کہ چونکہ چیٹ زیادہ "آزاد بات چیت" کی اجازت دیتا ہے، بہت عمومی سوالات پوچھنا آسان ہے جن کا جواب دینا مشکل ہوتا ہے، تو آپ کو جوابات نہ ملیں۔ |
||||
|
|
||||
|
GitHub میں، template آپ کو صحیح سوال لکھنے میں رہنمائی کرے گا تاکہ آپ آسانی سے اچھا جواب حاصل کر سکیں، یا پوچھنے سے پہلے ہی مسئلہ خود حل کر لیں۔ اور GitHub میں، میں یقینی بنا سکتا ہوں کہ میں ہمیشہ سب کا جواب دوں، چاہے کچھ وقت لگے۔ میں چیٹ systems کے ساتھ ذاتی طور پر ایسا نہیں کر سکتا۔ 😅 |
||||
|
|
||||
|
چیٹ systems میں بات چیت GitHub کی طرح آسانی سے تلاش کے قابل بھی نہیں ہوتی، تو سوالات اور جوابات بات چیت میں گم ہو سکتے ہیں۔ اور صرف GitHub والے [FastAPI Expert](fastapi-people.md#fastapi-experts) بننے میں شمار ہوتے ہیں، تو آپ کو GitHub میں زیادہ توجہ ملے گی۔ |
||||
|
|
||||
|
دوسری طرف، چیٹ systems میں ہزاروں صارفین ہیں، تو اس بات کا اچھا امکان ہے کہ آپ کو تقریباً ہر وقت وہاں کوئی بات کرنے والا مل جائے۔ 😄 |
||||
|
|
||||
|
## مصنف کی سرپرستی کریں { #sponsor-the-author } |
||||
|
|
||||
|
اگر آپ کا **product/company** **FastAPI** پر منحصر ہے یا اس سے متعلق ہے اور آپ اس کے صارفین تک پہنچنا چاہتے ہیں، تو آپ [GitHub sponsors](https://github.com/sponsors/tiangolo) کے ذریعے مصنف (مجھے) کی سرپرستی کر سکتے ہیں۔ tier کے لحاظ سے، آپ کو کچھ اضافی فوائد مل سکتے ہیں، جیسے docs میں badge۔ 🎁 |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
شکریہ! 🚀 |
||||
@ -0,0 +1,79 @@ |
|||||
|
# تاریخ، ڈیزائن اور مستقبل { #history-design-and-future } |
||||
|
|
||||
|
کچھ عرصہ پہلے، [ایک **FastAPI** صارف نے پوچھا](https://github.com/fastapi/fastapi/issues/3#issuecomment-454956920): |
||||
|
|
||||
|
> اس project کی تاریخ کیا ہے؟ ایسا لگتا ہے جیسے یہ چند ہفتوں میں کہیں سے نکل کر شاندار ہو گیا [...] |
||||
|
|
||||
|
یہاں اس تاریخ کا تھوڑا سا حصہ ہے۔ |
||||
|
|
||||
|
## متبادل { #alternatives } |
||||
|
|
||||
|
میں کئی سالوں سے پیچیدہ ضروریات کے ساتھ APIs بنا رہا تھا (Machine Learning، distributed systems، asynchronous jobs، NoSQL databases وغیرہ)، developers کی کئی ٹیموں کی قیادت کرتے ہوئے۔ |
||||
|
|
||||
|
اس کے حصے کے طور پر، مجھے بہت سے متبادل کی تحقیق، جانچ اور استعمال کرنے کی ضرورت پڑی۔ |
||||
|
|
||||
|
**FastAPI** کی تاریخ بہت حد تک اس کے پیش رو ٹولز کی تاریخ ہے۔ |
||||
|
|
||||
|
جیسا کہ [متبادل](alternatives.md) کے سیکشن میں کہا گیا ہے: |
||||
|
|
||||
|
<blockquote markdown="1"> |
||||
|
|
||||
|
**FastAPI** موجود نہ ہوتا اگر دوسروں کا پچھلا کام نہ ہوتا۔ |
||||
|
|
||||
|
پہلے بہت سے tools بنائے گئے ہیں جنہوں نے اس کی تخلیق کی تحریک دی۔ |
||||
|
|
||||
|
میں کئی سالوں سے نیا framework بنانے سے گریز کرتا رہا۔ پہلے میں نے **FastAPI** کی تمام features کو بہت سے مختلف frameworks، plug-ins، اور tools استعمال کرکے حل کرنے کی کوشش کی۔ |
||||
|
|
||||
|
لیکن کسی وقت، کوئی اور راستہ نہیں تھا سوائے اس کے کہ کچھ ایسا بنایا جائے جو یہ تمام features فراہم کرے، پچھلے tools سے بہترین آئیڈیاز لے کر، اور انہیں بہترین ممکنہ طریقے سے ملا کر، زبان کی ان features کو استعمال کرتے ہوئے جو پہلے دستیاب نہیں تھیں (Python 3.6+ type hints)۔ |
||||
|
|
||||
|
</blockquote> |
||||
|
|
||||
|
## تحقیق { #investigation } |
||||
|
|
||||
|
تمام پچھلے متبادل استعمال کرکے مجھے ان سب سے سیکھنے، آئیڈیاز لینے، اور انہیں بہترین طریقے سے ملانے کا موقع ملا جو میں اپنے اور اپنی ٹیموں کے لیے ڈھونڈ سکتا تھا۔ |
||||
|
|
||||
|
مثال کے طور پر، یہ واضح تھا کہ مثالی طور پر اسے standard Python type hints پر مبنی ہونا چاہیے۔ |
||||
|
|
||||
|
نیز، بہترین طریقہ یہ تھا کہ پہلے سے موجود standards استعمال کیے جائیں۔ |
||||
|
|
||||
|
تو **FastAPI** کو code کرنا شروع کرنے سے پہلے بھی، میں نے کئی مہینے OpenAPI، JSON Schema، OAuth2 وغیرہ کی specifications کا مطالعہ کرنے میں صرف کیے۔ ان کے تعلق، اوورلیپ، اور فرق کو سمجھتے ہوئے۔ |
||||
|
|
||||
|
## ڈیزائن { #design } |
||||
|
|
||||
|
پھر میں نے کچھ وقت developer "API" کو ڈیزائن کرنے میں لگایا جو میں ایک صارف (FastAPI استعمال کرنے والے developer) کے طور پر چاہتا تھا۔ |
||||
|
|
||||
|
میں نے سب سے مقبول Python editors میں کئی آئیڈیاز ٹیسٹ کیے: PyCharm، VS Code، Jedi پر مبنی editors۔ |
||||
|
|
||||
|
آخری [Python Developer Survey](https://www.jetbrains.com/research/python-developers-survey-2018/#development-tools) کے مطابق، جو تقریباً 80% صارفین کا احاطہ کرتا ہے۔ |
||||
|
|
||||
|
اس کا مطلب ہے کہ **FastAPI** خاص طور پر 80% Python developers کے استعمال کردہ editors کے ساتھ ٹیسٹ کیا گیا۔ اور چونکہ زیادہ تر دوسرے editors ملتے جلتے کام کرتے ہیں، اس کے تمام فوائد عملی طور پر تمام editors کے لیے کام کریں گے۔ |
||||
|
|
||||
|
اس طرح مجھے code duplication کو زیادہ سے زیادہ کم کرنے، ہر جگہ completion حاصل کرنے، type اور error checks وغیرہ کے بہترین طریقے مل سکے۔ |
||||
|
|
||||
|
یہ سب اس طرح جو تمام developers کو بہترین development experience فراہم کرے۔ |
||||
|
|
||||
|
## ضروریات { #requirements } |
||||
|
|
||||
|
کئی متبادل ٹیسٹ کرنے کے بعد، میں نے فیصلہ کیا کہ میں اس کے فوائد کی وجہ سے [**Pydantic**](https://docs.pydantic.dev/) استعمال کروں گا۔ |
||||
|
|
||||
|
پھر میں نے اس میں تعاون کیا، اسے JSON Schema کے ساتھ مکمل طور پر مطابق بنانے، constraint declarations define کرنے کے مختلف طریقوں کی سہولت دینے، اور کئی editors میں ٹیسٹوں کی بنیاد پر editor support (type checks، autocompletion) بہتر بنانے کے لیے۔ |
||||
|
|
||||
|
development کے دوران، میں نے [**Starlette**](https://www.starlette.dev/) میں بھی تعاون کیا، جو دوسری اہم ضرورت تھی۔ |
||||
|
|
||||
|
## ترقی { #development } |
||||
|
|
||||
|
جب میں نے **FastAPI** خود بنانا شروع کیا، زیادہ تر حصے پہلے سے اپنی جگہ تھے، ڈیزائن مقرر تھا، ضروریات اور tools تیار تھے، اور standards اور specifications کا علم واضح اور تازہ تھا۔ |
||||
|
|
||||
|
## مستقبل { #future } |
||||
|
|
||||
|
اس مقام تک، یہ پہلے سے واضح ہے کہ **FastAPI** اپنے آئیڈیاز کے ساتھ بہت سے لوگوں کے لیے مفید ہے۔ |
||||
|
|
||||
|
بہت سے use cases کے لیے اسے پچھلے متبادل پر ترجیح دی جا رہی ہے۔ |
||||
|
|
||||
|
بہت سے developers اور ٹیمیں پہلے سے اپنے projects کے لیے **FastAPI** پر انحصار کرتی ہیں (بشمول میں اور میری ٹیم)۔ |
||||
|
|
||||
|
لیکن پھر بھی، بہت سی بہتری اور features آنے والی ہیں۔ |
||||
|
|
||||
|
**FastAPI** کا مستقبل بہت روشن ہے۔ |
||||
|
|
||||
|
اور [آپ کی مدد](help-fastapi.md) کی بہت قدر کی جاتی ہے۔ |
||||
@ -0,0 +1,17 @@ |
|||||
|
# پرانے 403 Authentication Error Status Codes استعمال کریں { #use-old-403-authentication-error-status-codes } |
||||
|
|
||||
|
FastAPI ورژن `0.122.0` سے پہلے، جب integrated security utilities authentication ناکام ہونے پر client کو error واپس کرتی تھیں، تو وہ HTTP status code `403 Forbidden` استعمال کرتی تھیں۔ |
||||
|
|
||||
|
FastAPI ورژن `0.122.0` سے شروع کرتے ہوئے، وہ زیادہ مناسب HTTP status code `401 Unauthorized` استعمال کرتی ہیں، اور HTTP specifications کی پیروی کرتے ہوئے response میں ایک معقول `WWW-Authenticate` header واپس کرتی ہیں، [RFC 7235](https://datatracker.ietf.org/doc/html/rfc7235#section-3.1)، [RFC 9110](https://datatracker.ietf.org/doc/html/rfc9110#name-401-unauthorized)۔ |
||||
|
|
||||
|
لیکن اگر کسی وجہ سے آپ کے clients پرانے رویے پر منحصر ہیں، تو آپ اپنی security classes میں `make_not_authenticated_error` method کو override کر کے واپس پرانے رویے پر جا سکتے ہیں۔ |
||||
|
|
||||
|
مثال کے طور پر، آپ `HTTPBearer` کی ایک subclass بنا سکتے ہیں جو default `401 Unauthorized` error کی بجائے `403 Forbidden` error واپس کرے: |
||||
|
|
||||
|
{* ../../docs_src/authentication_error_status_code/tutorial001_an_py310.py hl[9:13] *} |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
نوٹ کریں کہ function exception instance واپس کرتا ہے، اسے raise نہیں کرتا۔ Raise کرنا باقی اندرونی کوڈ میں ہوتا ہے۔ |
||||
|
|
||||
|
/// |
||||
@ -0,0 +1,56 @@ |
|||||
|
# مشروط OpenAPI { #conditional-openapi } |
||||
|
|
||||
|
اگر آپ کو ضرورت ہو، تو آپ settings اور environment variables استعمال کر کے ماحول کے مطابق OpenAPI کو مشروط طور پر ترتیب دے سکتے ہیں، اور یہاں تک کہ اسے مکمل طور پر غیر فعال بھی کر سکتے ہیں۔ |
||||
|
|
||||
|
## سیکیورٹی، APIs، اور docs کے بارے میں { #about-security-apis-and-docs } |
||||
|
|
||||
|
اپنے documentation user interfaces کو production میں چھپانا آپ کی API کو محفوظ کرنے کا *صحیح طریقہ نہیں* ہونا چاہیے۔ |
||||
|
|
||||
|
یہ آپ کی API میں کوئی اضافی سیکیورٹی نہیں جوڑتا، *path operations* اب بھی وہیں دستیاب رہیں گی جہاں وہ ہیں۔ |
||||
|
|
||||
|
اگر آپ کے کوڈ میں کوئی سیکیورٹی خامی ہے، تو وہ پھر بھی موجود رہے گی۔ |
||||
|
|
||||
|
Documentation چھپانا صرف آپ کی API کے ساتھ تعامل کو سمجھنا مشکل بنا دیتا ہے، اور production میں اسے debug کرنا بھی مشکل ہو سکتا ہے۔ اسے سادہ طور پر [Security through obscurity](https://en.wikipedia.org/wiki/Security_through_obscurity) کی ایک شکل سمجھا جا سکتا ہے۔ |
||||
|
|
||||
|
اگر آپ اپنی API کو محفوظ کرنا چاہتے ہیں، تو کئی بہتر چیزیں ہیں جو آپ کر سکتے ہیں، مثال کے طور پر: |
||||
|
|
||||
|
* یقینی بنائیں کہ آپ کے request bodies اور responses کے لیے اچھی طرح سے defined Pydantic models ہیں۔ |
||||
|
* Dependencies استعمال کر کے تمام مطلوبہ permissions اور roles ترتیب دیں۔ |
||||
|
* کبھی بھی سادہ متن میں passwords ذخیرہ نہ کریں، صرف password hashes ذخیرہ کریں۔ |
||||
|
* معروف cryptographic ٹولز استعمال کریں اور لاگو کریں، جیسے pwdlib اور JWT tokens وغیرہ۔ |
||||
|
* جہاں ضرورت ہو OAuth2 scopes کے ساتھ مزید تفصیلی permission controls شامل کریں۔ |
||||
|
* ...وغیرہ۔ |
||||
|
|
||||
|
بہرحال، آپ کا کوئی بہت مخصوص استعمال کا معاملہ ہو سکتا ہے جہاں آپ کو واقعی کسی ماحول (مثلاً production) کے لیے یا environment variables کی ترتیبات کے مطابق API docs کو غیر فعال کرنا ہو۔ |
||||
|
|
||||
|
## Settings اور env vars سے مشروط OpenAPI { #conditional-openapi-from-settings-and-env-vars } |
||||
|
|
||||
|
آپ آسانی سے وہی Pydantic settings استعمال کر سکتے ہیں اپنے تیار کردہ OpenAPI اور docs UIs کو ترتیب دینے کے لیے۔ |
||||
|
|
||||
|
مثال کے طور پر: |
||||
|
|
||||
|
{* ../../docs_src/conditional_openapi/tutorial001_py310.py hl[6,11] *} |
||||
|
|
||||
|
یہاں ہم `openapi_url` setting کو `"/openapi.json"` کی اسی default قدر کے ساتھ declare کرتے ہیں۔ |
||||
|
|
||||
|
اور پھر ہم اسے `FastAPI` app بناتے وقت استعمال کرتے ہیں۔ |
||||
|
|
||||
|
پھر آپ `OPENAPI_URL` environment variable کو خالی string پر سیٹ کر کے OpenAPI (بشمول UI docs) کو غیر فعال کر سکتے ہیں، اس طرح: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ OPENAPI_URL= uvicorn main:app |
||||
|
|
||||
|
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
پھر اگر آپ `/openapi.json`، `/docs`، یا `/redoc` کے URLs پر جائیں تو آپ کو صرف `404 Not Found` error ملے گا جیسے: |
||||
|
|
||||
|
```JSON |
||||
|
{ |
||||
|
"detail": "Not Found" |
||||
|
} |
||||
|
``` |
||||
@ -0,0 +1,70 @@ |
|||||
|
# Swagger UI کی ترتیب { #configure-swagger-ui } |
||||
|
|
||||
|
آپ کچھ اضافی [Swagger UI parameters](https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/) ترتیب دے سکتے ہیں۔ |
||||
|
|
||||
|
انہیں ترتیب دینے کے لیے، `FastAPI()` app object بناتے وقت یا `get_swagger_ui_html()` function میں `swagger_ui_parameters` argument پاس کریں۔ |
||||
|
|
||||
|
`swagger_ui_parameters` ایک dictionary قبول کرتا ہے جس میں ترتیبات براہ راست Swagger UI کو بھیجی جاتی ہیں۔ |
||||
|
|
||||
|
FastAPI ترتیبات کو **JSON** میں تبدیل کرتا ہے تاکہ وہ JavaScript کے ساتھ ہم آہنگ ہوں، کیونکہ Swagger UI کو اسی کی ضرورت ہوتی ہے۔ |
||||
|
|
||||
|
## Syntax Highlighting غیر فعال کریں { #disable-syntax-highlighting } |
||||
|
|
||||
|
مثال کے طور پر، آپ Swagger UI میں syntax highlighting غیر فعال کر سکتے ہیں۔ |
||||
|
|
||||
|
Settings تبدیل کیے بغیر، syntax highlighting بطور default فعال ہوتی ہے: |
||||
|
|
||||
|
<img src="/img/tutorial/extending-openapi/image02.png"> |
||||
|
|
||||
|
لیکن آپ `syntaxHighlight` کو `False` سیٹ کر کے اسے غیر فعال کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/configure_swagger_ui/tutorial001_py310.py hl[3] *} |
||||
|
|
||||
|
...اور پھر Swagger UI مزید syntax highlighting نہیں دکھائے گا: |
||||
|
|
||||
|
<img src="/img/tutorial/extending-openapi/image03.png"> |
||||
|
|
||||
|
## Theme تبدیل کریں { #change-the-theme } |
||||
|
|
||||
|
اسی طرح آپ `"syntaxHighlight.theme"` key کے ساتھ syntax highlighting theme سیٹ کر سکتے ہیں (نوٹ کریں کہ اس میں درمیان میں ایک dot ہے): |
||||
|
|
||||
|
{* ../../docs_src/configure_swagger_ui/tutorial002_py310.py hl[3] *} |
||||
|
|
||||
|
یہ ترتیب syntax highlighting کی رنگ theme تبدیل کرے گی: |
||||
|
|
||||
|
<img src="/img/tutorial/extending-openapi/image04.png"> |
||||
|
|
||||
|
## Default Swagger UI Parameters تبدیل کریں { #change-default-swagger-ui-parameters } |
||||
|
|
||||
|
FastAPI میں زیادہ تر استعمال کے معاملات کے لیے کچھ default ترتیبی parameters شامل ہیں۔ |
||||
|
|
||||
|
اس میں یہ default ترتیبات شامل ہیں: |
||||
|
|
||||
|
{* ../../fastapi/openapi/docs.py ln[9:24] hl[18:24] *} |
||||
|
|
||||
|
آپ `swagger_ui_parameters` argument میں مختلف قدر سیٹ کر کے ان میں سے کسی کو بھی override کر سکتے ہیں۔ |
||||
|
|
||||
|
مثال کے طور پر، `deepLinking` کو غیر فعال کرنے کے لیے آپ یہ settings `swagger_ui_parameters` میں پاس کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/configure_swagger_ui/tutorial003_py310.py hl[3] *} |
||||
|
|
||||
|
## دیگر Swagger UI Parameters { #other-swagger-ui-parameters } |
||||
|
|
||||
|
تمام ممکنہ ترتیبات دیکھنے کے لیے جو آپ استعمال کر سکتے ہیں، سرکاری [Swagger UI parameters کی دستاویزات](https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/) پڑھیں۔ |
||||
|
|
||||
|
## صرف JavaScript والی settings { #javascript-only-settings } |
||||
|
|
||||
|
Swagger UI دیگر ترتیبات کی بھی اجازت دیتا ہے جو **صرف JavaScript** objects ہیں (مثال کے طور پر، JavaScript functions)۔ |
||||
|
|
||||
|
FastAPI میں یہ صرف JavaScript والی `presets` settings بھی شامل ہیں: |
||||
|
|
||||
|
```JavaScript |
||||
|
presets: [ |
||||
|
SwaggerUIBundle.presets.apis, |
||||
|
SwaggerUIBundle.SwaggerUIStandalonePreset |
||||
|
] |
||||
|
``` |
||||
|
|
||||
|
یہ **JavaScript** objects ہیں، strings نہیں، اس لیے آپ انہیں Python کوڈ سے براہ راست پاس نہیں کر سکتے۔ |
||||
|
|
||||
|
اگر آپ کو اس طرح کی صرف JavaScript والی ترتیبات استعمال کرنے کی ضرورت ہے، تو آپ اوپر بیان کردہ طریقوں میں سے کوئی ایک استعمال کر سکتے ہیں۔ تمام Swagger UI *path operation* کو override کریں اور جو بھی JavaScript آپ کو چاہیے دستی طور پر لکھیں۔ |
||||
@ -0,0 +1,185 @@ |
|||||
|
# حسب ضرورت Docs UI Static Assets (Self-Hosting) { #custom-docs-ui-static-assets-self-hosting } |
||||
|
|
||||
|
API docs **Swagger UI** اور **ReDoc** استعمال کرتے ہیں، اور ان میں سے ہر ایک کو کچھ JavaScript اور CSS فائلوں کی ضرورت ہوتی ہے۔ |
||||
|
|
||||
|
بطور default، وہ فائلیں ایک <abbr title="Content Delivery Network: ایک سروس، جو عام طور پر کئی servers پر مشتمل ہوتی ہے، جو static فائلیں فراہم کرتی ہے، جیسے JavaScript اور CSS۔ یہ عام طور پر client کے قریب ترین server سے فائلیں فراہم کرنے کے لیے استعمال ہوتی ہے، جو کارکردگی بہتر بناتی ہے۔">CDN</abbr> سے فراہم کی جاتی ہیں۔ |
||||
|
|
||||
|
لیکن اسے اپنی مرضی کے مطابق بنانا ممکن ہے، آپ کوئی مخصوص CDN سیٹ کر سکتے ہیں، یا فائلیں خود فراہم کر سکتے ہیں۔ |
||||
|
|
||||
|
## JavaScript اور CSS کے لیے حسب ضرورت CDN { #custom-cdn-for-javascript-and-css } |
||||
|
|
||||
|
فرض کریں کہ آپ ایک مختلف <abbr title="Content Delivery Network">CDN</abbr> استعمال کرنا چاہتے ہیں، مثال کے طور پر آپ `https://unpkg.com/` استعمال کرنا چاہتے ہیں۔ |
||||
|
|
||||
|
یہ مفید ہو سکتا ہے اگر مثلاً آپ کسی ایسے ملک میں رہتے ہیں جو کچھ URLs پر پابندی لگاتا ہے۔ |
||||
|
|
||||
|
### خود کار docs غیر فعال کریں { #disable-the-automatic-docs } |
||||
|
|
||||
|
پہلا مرحلہ خود کار docs کو غیر فعال کرنا ہے، کیونکہ بطور default، وہ default CDN استعمال کرتے ہیں۔ |
||||
|
|
||||
|
انہیں غیر فعال کرنے کے لیے، اپنی `FastAPI` app بناتے وقت ان کے URLs کو `None` پر سیٹ کریں: |
||||
|
|
||||
|
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[8] *} |
||||
|
|
||||
|
### حسب ضرورت docs شامل کریں { #include-the-custom-docs } |
||||
|
|
||||
|
اب آپ حسب ضرورت docs کے لیے *path operations* بنا سکتے ہیں۔ |
||||
|
|
||||
|
آپ docs کے لیے HTML صفحات بنانے کے لیے FastAPI کے اندرونی functions دوبارہ استعمال کر سکتے ہیں، اور انہیں مطلوبہ arguments پاس کر سکتے ہیں: |
||||
|
|
||||
|
* `openapi_url`: وہ URL جہاں سے docs کا HTML صفحہ آپ کی API کا OpenAPI schema حاصل کر سکتا ہے۔ آپ یہاں `app.openapi_url` attribute استعمال کر سکتے ہیں۔ |
||||
|
* `title`: آپ کی API کا عنوان۔ |
||||
|
* `oauth2_redirect_url`: آپ default استعمال کرنے کے لیے یہاں `app.swagger_ui_oauth2_redirect_url` استعمال کر سکتے ہیں۔ |
||||
|
* `swagger_js_url`: وہ URL جہاں سے آپ کے Swagger UI docs کا HTML **JavaScript** فائل حاصل کر سکتا ہے۔ یہ حسب ضرورت CDN URL ہے۔ |
||||
|
* `swagger_css_url`: وہ URL جہاں سے آپ کے Swagger UI docs کا HTML **CSS** فائل حاصل کر سکتا ہے۔ یہ حسب ضرورت CDN URL ہے۔ |
||||
|
|
||||
|
اور اسی طرح ReDoc کے لیے... |
||||
|
|
||||
|
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[2:6,11:19,22:24,27:33] *} |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
`swagger_ui_redirect` کے لیے *path operation* اس وقت کام آتا ہے جب آپ OAuth2 استعمال کرتے ہیں۔ |
||||
|
|
||||
|
اگر آپ اپنی API کو کسی OAuth2 provider کے ساتھ integrate کرتے ہیں، تو آپ authenticate ہو کر حاصل کردہ credentials کے ساتھ API docs پر واپس آ سکیں گے۔ اور حقیقی OAuth2 authentication کا استعمال کرتے ہوئے اس کے ساتھ تعامل کر سکیں گے۔ |
||||
|
|
||||
|
Swagger UI پردے کے پیچھے آپ کے لیے اسے سنبھالے گا، لیکن اسے اس "redirect" helper کی ضرورت ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### جانچ کے لیے *path operation* بنائیں { #create-a-path-operation-to-test-it } |
||||
|
|
||||
|
اب، سب کچھ کام کر رہا ہے یہ جانچنے کے لیے، ایک *path operation* بنائیں: |
||||
|
|
||||
|
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[36:38] *} |
||||
|
|
||||
|
### جانچ کریں { #test-it } |
||||
|
|
||||
|
اب، آپ اپنے docs پر [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) جا کر صفحہ دوبارہ load کر سکتے ہیں، یہ نئے CDN سے assets load کرے گا۔ |
||||
|
|
||||
|
## Docs کے لیے JavaScript اور CSS خود host کریں { #self-hosting-javascript-and-css-for-docs } |
||||
|
|
||||
|
JavaScript اور CSS خود host کرنا مفید ہو سکتا ہے اگر، مثال کے طور پر، آپ کو اپنی app کو آف لائن بھی کام کرتے رہنے کی ضرورت ہے، بغیر کسی Internet رسائی کے، یا مقامی network میں۔ |
||||
|
|
||||
|
یہاں آپ دیکھیں گے کہ ان فائلوں کو اسی FastAPI app میں خود کیسے فراہم کیا جائے، اور docs کو ان کا استعمال کرنے کے لیے کیسے ترتیب دیا جائے۔ |
||||
|
|
||||
|
### پروجیکٹ کی فائل ساخت { #project-file-structure } |
||||
|
|
||||
|
فرض کریں آپ کے پروجیکٹ کی فائل ساخت اس طرح نظر آتی ہے: |
||||
|
|
||||
|
``` |
||||
|
. |
||||
|
├── app |
||||
|
│ ├── __init__.py |
||||
|
│ ├── main.py |
||||
|
``` |
||||
|
|
||||
|
اب ان static فائلوں کو ذخیرہ کرنے کے لیے ایک directory بنائیں۔ |
||||
|
|
||||
|
آپ کی نئی فائل ساخت اس طرح نظر آ سکتی ہے: |
||||
|
|
||||
|
``` |
||||
|
. |
||||
|
├── app |
||||
|
│ ├── __init__.py |
||||
|
│ ├── main.py |
||||
|
└── static/ |
||||
|
``` |
||||
|
|
||||
|
### فائلیں ڈاؤن لوڈ کریں { #download-the-files } |
||||
|
|
||||
|
Docs کے لیے ضروری static فائلیں ڈاؤن لوڈ کریں اور انہیں اس `static/` directory میں رکھیں۔ |
||||
|
|
||||
|
آپ غالباً ہر لنک پر right-click کر کے "Save link as..." جیسا آپشن منتخب کر سکتے ہیں۔ |
||||
|
|
||||
|
**Swagger UI** یہ فائلیں استعمال کرتا ہے: |
||||
|
|
||||
|
* [`swagger-ui-bundle.js`](https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js) |
||||
|
* [`swagger-ui.css`](https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css) |
||||
|
|
||||
|
اور **ReDoc** یہ فائل استعمال کرتا ہے: |
||||
|
|
||||
|
* [`redoc.standalone.js`](https://cdn.jsdelivr.net/npm/redoc@2/bundles/redoc.standalone.js) |
||||
|
|
||||
|
اس کے بعد، آپ کی فائل ساخت اس طرح نظر آ سکتی ہے: |
||||
|
|
||||
|
``` |
||||
|
. |
||||
|
├── app |
||||
|
│ ├── __init__.py |
||||
|
│ ├── main.py |
||||
|
└── static |
||||
|
├── redoc.standalone.js |
||||
|
├── swagger-ui-bundle.js |
||||
|
└── swagger-ui.css |
||||
|
``` |
||||
|
|
||||
|
### Static فائلیں فراہم کریں { #serve-the-static-files } |
||||
|
|
||||
|
* `StaticFiles` import کریں۔ |
||||
|
* ایک مخصوص path پر `StaticFiles()` instance "Mount" کریں۔ |
||||
|
|
||||
|
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[7,11] *} |
||||
|
|
||||
|
### Static فائلوں کی جانچ کریں { #test-the-static-files } |
||||
|
|
||||
|
اپنی application شروع کریں اور [http://127.0.0.1:8000/static/redoc.standalone.js](http://127.0.0.1:8000/static/redoc.standalone.js) پر جائیں۔ |
||||
|
|
||||
|
آپ کو **ReDoc** کے لیے ایک بہت لمبی JavaScript فائل نظر آنی چاہیے۔ |
||||
|
|
||||
|
یہ کچھ اس طرح شروع ہو سکتی ہے: |
||||
|
|
||||
|
```JavaScript |
||||
|
/*! For license information please see redoc.standalone.js.LICENSE.txt */ |
||||
|
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("null")): |
||||
|
... |
||||
|
``` |
||||
|
|
||||
|
یہ تصدیق کرتا ہے کہ آپ اپنی app سے static فائلیں فراہم کر سکتے ہیں، اور آپ نے docs کی static فائلیں صحیح جگہ رکھی ہیں۔ |
||||
|
|
||||
|
اب ہم app کو ان static فائلوں کو docs کے لیے استعمال کرنے کے لیے ترتیب دے سکتے ہیں۔ |
||||
|
|
||||
|
### Static فائلوں کے لیے خود کار docs غیر فعال کریں { #disable-the-automatic-docs-for-static-files } |
||||
|
|
||||
|
حسب ضرورت CDN استعمال کرنے کی طرح، پہلا مرحلہ خود کار docs کو غیر فعال کرنا ہے، کیونکہ وہ بطور default CDN استعمال کرتے ہیں۔ |
||||
|
|
||||
|
انہیں غیر فعال کرنے کے لیے، اپنی `FastAPI` app بناتے وقت ان کے URLs کو `None` پر سیٹ کریں: |
||||
|
|
||||
|
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[9] *} |
||||
|
|
||||
|
### Static فائلوں کے لیے حسب ضرورت docs شامل کریں { #include-the-custom-docs-for-static-files } |
||||
|
|
||||
|
اور حسب ضرورت CDN کی طرح، اب آپ حسب ضرورت docs کے لیے *path operations* بنا سکتے ہیں۔ |
||||
|
|
||||
|
دوبارہ، آپ docs کے لیے HTML صفحات بنانے کے لیے FastAPI کے اندرونی functions دوبارہ استعمال کر سکتے ہیں، اور انہیں مطلوبہ arguments پاس کر سکتے ہیں: |
||||
|
|
||||
|
* `openapi_url`: وہ URL جہاں سے docs کا HTML صفحہ آپ کی API کا OpenAPI schema حاصل کر سکتا ہے۔ آپ یہاں `app.openapi_url` attribute استعمال کر سکتے ہیں۔ |
||||
|
* `title`: آپ کی API کا عنوان۔ |
||||
|
* `oauth2_redirect_url`: آپ default استعمال کرنے کے لیے یہاں `app.swagger_ui_oauth2_redirect_url` استعمال کر سکتے ہیں۔ |
||||
|
* `swagger_js_url`: وہ URL جہاں سے آپ کے Swagger UI docs کا HTML **JavaScript** فائل حاصل کر سکتا ہے۔ **یہ وہی ہے جو آپ کی اپنی app اب فراہم کر رہی ہے**۔ |
||||
|
* `swagger_css_url`: وہ URL جہاں سے آپ کے Swagger UI docs کا HTML **CSS** فائل حاصل کر سکتا ہے۔ **یہ وہی ہے جو آپ کی اپنی app اب فراہم کر رہی ہے**۔ |
||||
|
|
||||
|
اور اسی طرح ReDoc کے لیے... |
||||
|
|
||||
|
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[2:6,14:22,25:27,30:36] *} |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
`swagger_ui_redirect` کے لیے *path operation* اس وقت کام آتا ہے جب آپ OAuth2 استعمال کرتے ہیں۔ |
||||
|
|
||||
|
اگر آپ اپنی API کو کسی OAuth2 provider کے ساتھ integrate کرتے ہیں، تو آپ authenticate ہو کر حاصل کردہ credentials کے ساتھ API docs پر واپس آ سکیں گے۔ اور حقیقی OAuth2 authentication کا استعمال کرتے ہوئے اس کے ساتھ تعامل کر سکیں گے۔ |
||||
|
|
||||
|
Swagger UI پردے کے پیچھے آپ کے لیے اسے سنبھالے گا، لیکن اسے اس "redirect" helper کی ضرورت ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### Static فائلوں کی جانچ کے لیے *path operation* بنائیں { #create-a-path-operation-to-test-static-files } |
||||
|
|
||||
|
اب، سب کچھ کام کر رہا ہے یہ جانچنے کے لیے، ایک *path operation* بنائیں: |
||||
|
|
||||
|
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[39:41] *} |
||||
|
|
||||
|
### Static فائلوں کے UI کی جانچ { #test-static-files-ui } |
||||
|
|
||||
|
اب، آپ اپنا WiFi بند کر کے اپنے docs پر [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) جا سکتے ہیں اور صفحہ دوبارہ load کر سکتے ہیں۔ |
||||
|
|
||||
|
اور Internet کے بغیر بھی، آپ اپنی API کے docs دیکھ سکیں گے اور اس کے ساتھ تعامل کر سکیں گے۔ |
||||
@ -0,0 +1,109 @@ |
|||||
|
# حسب ضرورت Request اور APIRoute class { #custom-request-and-apiroute-class } |
||||
|
|
||||
|
بعض صورتوں میں، آپ `Request` اور `APIRoute` classes کی منطق کو override کرنا چاہ سکتے ہیں۔ |
||||
|
|
||||
|
خاص طور پر، یہ middleware میں منطق رکھنے کا ایک اچھا متبادل ہو سکتا ہے۔ |
||||
|
|
||||
|
مثال کے طور پر، اگر آپ request body کو آپ کی application کی طرف سے process ہونے سے پہلے پڑھنا یا تبدیل کرنا چاہتے ہیں۔ |
||||
|
|
||||
|
/// danger |
||||
|
|
||||
|
یہ ایک "advanced" خصوصیت ہے۔ |
||||
|
|
||||
|
اگر آپ ابھی **FastAPI** شروع کر رہے ہیں تو شاید آپ اس حصے کو چھوڑنا چاہیں گے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## استعمال کے معاملات { #use-cases } |
||||
|
|
||||
|
کچھ استعمال کے معاملات میں شامل ہیں: |
||||
|
|
||||
|
* غیر JSON request bodies کو JSON میں تبدیل کرنا (مثلاً [`msgpack`](https://msgpack.org/index.html))۔ |
||||
|
* gzip سے compress شدہ request bodies کو decompress کرنا۔ |
||||
|
* تمام request bodies کو خود کار طریقے سے log کرنا۔ |
||||
|
|
||||
|
## حسب ضرورت request body encodings کو سنبھالنا { #handling-custom-request-body-encodings } |
||||
|
|
||||
|
آئیے دیکھتے ہیں کہ gzip requests کو decompress کرنے کے لیے حسب ضرورت `Request` subclass کیسے استعمال کی جائے۔ |
||||
|
|
||||
|
اور اس حسب ضرورت request class کو استعمال کرنے کے لیے `APIRoute` subclass کیسے بنائی جائے۔ |
||||
|
|
||||
|
### حسب ضرورت `GzipRequest` class بنائیں { #create-a-custom-gziprequest-class } |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
یہ ایک مثال ہے جو دکھاتی ہے کہ یہ کیسے کام کرتا ہے، اگر آپ کو Gzip سپورٹ کی ضرورت ہے، تو آپ فراہم کردہ [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware) استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
سب سے پہلے، ہم ایک `GzipRequest` class بناتے ہیں، جو مناسب header کی موجودگی میں body کو decompress کرنے کے لیے `Request.body()` method کو overwrite کرے گی۔ |
||||
|
|
||||
|
اگر header میں `gzip` نہیں ہے، تو یہ body کو decompress کرنے کی کوشش نہیں کرے گی۔ |
||||
|
|
||||
|
اس طرح، ایک ہی route class gzip سے compress شدہ یا بغیر compress شدہ requests کو سنبھال سکتی ہے۔ |
||||
|
|
||||
|
{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[9:16] *} |
||||
|
|
||||
|
### حسب ضرورت `GzipRoute` class بنائیں { #create-a-custom-gziproute-class } |
||||
|
|
||||
|
اس کے بعد، ہم `fastapi.routing.APIRoute` کی ایک حسب ضرورت subclass بناتے ہیں جو `GzipRequest` استعمال کرے گی۔ |
||||
|
|
||||
|
اس بار، یہ `APIRoute.get_route_handler()` method کو overwrite کرے گی۔ |
||||
|
|
||||
|
یہ method ایک function واپس کرتا ہے۔ اور وہ function ہی ہے جو request وصول کرے گا اور response واپس کرے گا۔ |
||||
|
|
||||
|
یہاں ہم اسے اصل request سے `GzipRequest` بنانے کے لیے استعمال کرتے ہیں۔ |
||||
|
|
||||
|
{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[19:27] *} |
||||
|
|
||||
|
/// note | تکنیکی تفصیلات |
||||
|
|
||||
|
ایک `Request` میں `request.scope` attribute ہوتا ہے، جو صرف ایک Python `dict` ہے جس میں request سے متعلق metadata ہوتا ہے۔ |
||||
|
|
||||
|
ایک `Request` میں `request.receive` بھی ہوتا ہے، جو request کی body کو "وصول" کرنے کا function ہے۔ |
||||
|
|
||||
|
`scope` `dict` اور `receive` function دونوں ASGI specification کا حصہ ہیں۔ |
||||
|
|
||||
|
اور یہ دو چیزیں، `scope` اور `receive`، نئی `Request` instance بنانے کے لیے درکار ہیں۔ |
||||
|
|
||||
|
`Request` کے بارے میں مزید جاننے کے لیے [Starlette کی Requests کے بارے میں دستاویزات](https://www.starlette.dev/requests/) دیکھیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
`GzipRequest.get_route_handler` کی واپس کردہ function صرف اتنا مختلف کام کرتی ہے کہ `Request` کو `GzipRequest` میں تبدیل کرتی ہے۔ |
||||
|
|
||||
|
ایسا کرنے سے، ہماری `GzipRequest` ہماری *path operations* کو بھیجنے سے پہلے ڈیٹا کو decompress (اگر ضروری ہو) کا خیال رکھے گی۔ |
||||
|
|
||||
|
اس کے بعد، تمام processing کی منطق ایک جیسی ہی ہے۔ |
||||
|
|
||||
|
لیکن ہماری `GzipRequest.body` میں تبدیلیوں کی وجہ سے، request body خود بخود decompress ہو جائے گی جب **FastAPI** اسے ضرورت کے وقت load کرے گا۔ |
||||
|
|
||||
|
## Exception handler میں request body تک رسائی { #accessing-the-request-body-in-an-exception-handler } |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
اسی مسئلے کو حل کرنے کے لیے، `RequestValidationError` کے لیے حسب ضرورت handler میں `body` استعمال کرنا شاید بہت آسان ہے ([Handling Errors](../tutorial/handling-errors.md#use-the-requestvalidationerror-body))۔ |
||||
|
|
||||
|
لیکن یہ مثال اب بھی درست ہے اور یہ دکھاتی ہے کہ اندرونی اجزاء کے ساتھ کیسے تعامل کیا جائے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
ہم اسی طریقے کو exception handler میں request body تک رسائی کے لیے بھی استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
ہمیں بس request کو `try`/`except` block کے اندر سنبھالنا ہے: |
||||
|
|
||||
|
{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[14,16] *} |
||||
|
|
||||
|
اگر کوئی exception واقع ہو، تو `Request` instance ابھی بھی scope میں ہوگی، تو ہم error کو سنبھالتے وقت request body کو پڑھ اور استعمال کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[17:19] *} |
||||
|
|
||||
|
## Router میں حسب ضرورت `APIRoute` class { #custom-apiroute-class-in-a-router } |
||||
|
|
||||
|
آپ `APIRouter` کا `route_class` parameter بھی سیٹ کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[26] *} |
||||
|
|
||||
|
اس مثال میں، `router` کے تحت *path operations* حسب ضرورت `TimedRoute` class استعمال کریں گی، اور response میں ایک اضافی `X-Response-Time` header ہوگا جس میں response تیار کرنے میں لگنے والا وقت ہوگا: |
||||
|
|
||||
|
{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[13:20] *} |
||||
@ -0,0 +1,80 @@ |
|||||
|
# OpenAPI کی توسیع { #extending-openapi } |
||||
|
|
||||
|
کچھ ایسے معاملات ہیں جہاں آپ کو تیار کردہ OpenAPI schema میں ترمیم کرنے کی ضرورت ہو سکتی ہے۔ |
||||
|
|
||||
|
اس حصے میں آپ دیکھیں گے کہ یہ کیسے کریں۔ |
||||
|
|
||||
|
## عام عمل { #the-normal-process } |
||||
|
|
||||
|
عام (default) عمل درج ذیل ہے۔ |
||||
|
|
||||
|
ایک `FastAPI` application (instance) میں `.openapi()` method ہوتا ہے جس سے OpenAPI schema واپس آنے کی توقع ہوتی ہے۔ |
||||
|
|
||||
|
Application object بنانے کے حصے کے طور پر، `/openapi.json` (یا جو بھی آپ نے اپنا `openapi_url` سیٹ کیا ہو) کے لیے ایک *path operation* رجسٹر ہوتی ہے۔ |
||||
|
|
||||
|
یہ صرف application کے `.openapi()` method کے نتیجے کے ساتھ JSON response واپس کرتی ہے۔ |
||||
|
|
||||
|
بطور default، `.openapi()` method `.openapi_schema` property کو چیک کرتی ہے کہ آیا اس میں مواد ہے اور اسے واپس کرتی ہے۔ |
||||
|
|
||||
|
اگر نہیں ہے، تو یہ `fastapi.openapi.utils.get_openapi` پر موجود utility function کا استعمال کرتے ہوئے انہیں تیار کرتی ہے۔ |
||||
|
|
||||
|
اور وہ `get_openapi()` function بطور parameters یہ وصول کرتا ہے: |
||||
|
|
||||
|
* `title`: OpenAPI کا عنوان، docs میں دکھایا جاتا ہے۔ |
||||
|
* `version`: آپ کی API کا ورژن، مثلاً `2.5.0`۔ |
||||
|
* `openapi_version`: استعمال شدہ OpenAPI specification کا ورژن۔ بطور default، تازہ ترین: `3.1.0`۔ |
||||
|
* `summary`: API کا مختصر خلاصہ۔ |
||||
|
* `description`: آپ کی API کی تفصیل، اس میں markdown شامل ہو سکتا ہے اور docs میں دکھایا جائے گا۔ |
||||
|
* `routes`: Routes کی فہرست، یہ ہر ایک رجسٹر شدہ *path operations* ہیں۔ یہ `app.routes` سے لیے جاتے ہیں۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
`summary` parameter OpenAPI 3.1.0 اور اس سے اوپر میں دستیاب ہے، جسے FastAPI 0.99.0 اور اس سے اوپر سپورٹ کرتا ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## Defaults کو override کرنا { #overriding-the-defaults } |
||||
|
|
||||
|
اوپر دی گئی معلومات کا استعمال کرتے ہوئے، آپ اسی utility function کو OpenAPI schema تیار کرنے کے لیے استعمال کر سکتے ہیں اور ہر اس حصے کو override کر سکتے ہیں جس کی آپ کو ضرورت ہے۔ |
||||
|
|
||||
|
مثال کے طور پر، آئیے [ReDoc کی OpenAPI extension شامل کریں تاکہ حسب ضرورت logo شامل ہو](https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md#x-logo)۔ |
||||
|
|
||||
|
### عام **FastAPI** { #normal-fastapi } |
||||
|
|
||||
|
سب سے پہلے، اپنی تمام **FastAPI** application معمول کے مطابق لکھیں: |
||||
|
|
||||
|
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[1,4,7:9] *} |
||||
|
|
||||
|
### OpenAPI schema تیار کریں { #generate-the-openapi-schema } |
||||
|
|
||||
|
پھر، `custom_openapi()` function کے اندر OpenAPI schema تیار کرنے کے لیے وہی utility function استعمال کریں: |
||||
|
|
||||
|
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[2,15:21] *} |
||||
|
|
||||
|
### OpenAPI schema میں ترمیم کریں { #modify-the-openapi-schema } |
||||
|
|
||||
|
اب آپ ReDoc extension شامل کر سکتے ہیں، OpenAPI schema میں `info` "object" میں حسب ضرورت `x-logo` شامل کر کے: |
||||
|
|
||||
|
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[22:24] *} |
||||
|
|
||||
|
### OpenAPI schema کو cache کریں { #cache-the-openapi-schema } |
||||
|
|
||||
|
آپ `.openapi_schema` property کو "cache" کے طور پر استعمال کر سکتے ہیں، اپنا تیار کردہ schema ذخیرہ کرنے کے لیے۔ |
||||
|
|
||||
|
اس طرح، آپ کی application کو ہر بار جب کوئی صارف آپ کے API docs کھولے schema دوبارہ تیار نہیں کرنا پڑے گا۔ |
||||
|
|
||||
|
یہ صرف ایک بار تیار ہوگا، اور پھر اگلی requests کے لیے وہی cached schema استعمال ہوگا۔ |
||||
|
|
||||
|
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[13:14,25:26] *} |
||||
|
|
||||
|
### Method کو override کریں { #override-the-method } |
||||
|
|
||||
|
اب آپ `.openapi()` method کو اپنے نئے function سے تبدیل کر سکتے ہیں۔ |
||||
|
|
||||
|
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[29] *} |
||||
|
|
||||
|
### جانچ کریں { #check-it } |
||||
|
|
||||
|
جب آپ [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc) پر جائیں گے تو آپ دیکھیں گے کہ آپ اپنا حسب ضرورت logo استعمال کر رہے ہیں (اس مثال میں، **FastAPI** کا logo): |
||||
|
|
||||
|
<img src="/img/tutorial/extending-openapi/image01.png"> |
||||
@ -0,0 +1,43 @@ |
|||||
|
# عمومی - طریقہ کار - ترکیبیں { #general-how-to-recipes } |
||||
|
|
||||
|
یہاں عمومی یا اکثر پوچھے جانے والے سوالات کے لیے دستاویزات میں دیگر مقامات کی طرف کئی اشارے ہیں۔ |
||||
|
|
||||
|
## ڈیٹا فلٹر کریں - Security { #filter-data-security } |
||||
|
|
||||
|
اس بات کو یقینی بنانے کے لیے کہ آپ ضرورت سے زیادہ ڈیٹا واپس نہ کریں، [Tutorial - Response Model - Return Type](../tutorial/response-model.md) کی دستاویزات پڑھیں۔ |
||||
|
|
||||
|
## Response کی کارکردگی بہتر بنائیں - Response Model - Return Type { #optimize-response-performance-response-model-return-type } |
||||
|
|
||||
|
JSON ڈیٹا واپس کرتے وقت کارکردگی بہتر بنانے کے لیے، return type یا response model استعمال کریں، اس طرح Pydantic بغیر Python سے گزرے Rust کی طرف سے JSON میں serialization سنبھالے گا۔ مزید معلومات کے لیے [Tutorial - Response Model - Return Type](../tutorial/response-model.md) کی دستاویزات پڑھیں۔ |
||||
|
|
||||
|
## دستاویزات کے Tags - OpenAPI { #documentation-tags-openapi } |
||||
|
|
||||
|
اپنی *path operations* میں tags شامل کرنے اور انہیں docs UI میں گروپ کرنے کے لیے، [Tutorial - Path Operation Configurations - Tags](../tutorial/path-operation-configuration.md#tags) کی دستاویزات پڑھیں۔ |
||||
|
|
||||
|
## دستاویزات کا خلاصہ اور تفصیل - OpenAPI { #documentation-summary-and-description-openapi } |
||||
|
|
||||
|
اپنی *path operations* میں summary اور description شامل کرنے اور انہیں docs UI میں دکھانے کے لیے، [Tutorial - Path Operation Configurations - Summary and Description](../tutorial/path-operation-configuration.md#summary-and-description) کی دستاویزات پڑھیں۔ |
||||
|
|
||||
|
## دستاویزات Response description - OpenAPI { #documentation-response-description-openapi } |
||||
|
|
||||
|
Response کی تفصیل جو docs UI میں دکھائی جاتی ہے اس کی وضاحت کرنے کے لیے، [Tutorial - Path Operation Configurations - Response description](../tutorial/path-operation-configuration.md#response-description) کی دستاویزات پڑھیں۔ |
||||
|
|
||||
|
## دستاویزات میں *Path Operation* کو Deprecate کریں - OpenAPI { #documentation-deprecate-a-path-operation-openapi } |
||||
|
|
||||
|
کسی *path operation* کو deprecate کرنے اور اسے docs UI میں دکھانے کے لیے، [Tutorial - Path Operation Configurations - Deprecation](../tutorial/path-operation-configuration.md#deprecate-a-path-operation) کی دستاویزات پڑھیں۔ |
||||
|
|
||||
|
## کسی بھی ڈیٹا کو JSON-compatible میں تبدیل کریں { #convert-any-data-to-json-compatible } |
||||
|
|
||||
|
کسی بھی ڈیٹا کو JSON-compatible میں تبدیل کرنے کے لیے، [Tutorial - JSON Compatible Encoder](../tutorial/encoder.md) کی دستاویزات پڑھیں۔ |
||||
|
|
||||
|
## OpenAPI Metadata - Docs { #openapi-metadata-docs } |
||||
|
|
||||
|
اپنے OpenAPI schema میں metadata شامل کرنے کے لیے، بشمول license، version، contact وغیرہ، [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md) کی دستاویزات پڑھیں۔ |
||||
|
|
||||
|
## OpenAPI Custom URL { #openapi-custom-url } |
||||
|
|
||||
|
OpenAPI URL کو اپنی مرضی کے مطابق بنانے (یا ہٹانے) کے لیے، [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#openapi-url) کی دستاویزات پڑھیں۔ |
||||
|
|
||||
|
## OpenAPI Docs URLs { #openapi-docs-urls } |
||||
|
|
||||
|
خود کار طریقے سے تیار کردہ docs user interfaces کے لیے استعمال ہونے والے URLs کو اپ ڈیٹ کرنے کے لیے، [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#docs-urls) کی دستاویزات پڑھیں۔ |
||||
@ -0,0 +1,60 @@ |
|||||
|
# GraphQL { #graphql } |
||||
|
|
||||
|
چونکہ **FastAPI** کی بنیاد **ASGI** standard پر ہے، اس لیے ASGI کے ساتھ ہم آہنگ کسی بھی **GraphQL** لائبریری کو آسانی سے شامل کیا جا سکتا ہے۔ |
||||
|
|
||||
|
آپ ایک ہی application میں عام FastAPI *path operations* کو GraphQL کے ساتھ ملا سکتے ہیں۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
**GraphQL** کچھ بہت مخصوص استعمال کے معاملات حل کرتا ہے۔ |
||||
|
|
||||
|
عام **web APIs** کے مقابلے میں اس کے **فوائد** اور **نقصانات** ہیں۔ |
||||
|
|
||||
|
یقینی بنائیں کہ آپ کے استعمال کے معاملے کے لیے **فوائد** کیا **نقصانات** کی تلافی کرتے ہیں۔ 🤓 |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## GraphQL لائبریریاں { #graphql-libraries } |
||||
|
|
||||
|
یہاں کچھ **GraphQL** لائبریریاں ہیں جن میں **ASGI** سپورٹ موجود ہے۔ آپ انہیں **FastAPI** کے ساتھ استعمال کر سکتے ہیں: |
||||
|
|
||||
|
* [Strawberry](https://strawberry.rocks/) 🍓 |
||||
|
* [FastAPI کے لیے دستاویزات](https://strawberry.rocks/docs/integrations/fastapi) کے ساتھ |
||||
|
* [Ariadne](https://ariadnegraphql.org/) |
||||
|
* [FastAPI کے لیے دستاویزات](https://ariadnegraphql.org/docs/fastapi-integration) کے ساتھ |
||||
|
* [Tartiflette](https://tartiflette.io/) |
||||
|
* ASGI integration فراہم کرنے کے لیے [Tartiflette ASGI](https://tartiflette.github.io/tartiflette-asgi/) کے ساتھ |
||||
|
* [Graphene](https://graphene-python.org/) |
||||
|
* [starlette-graphene3](https://github.com/ciscorn/starlette-graphene3) کے ساتھ |
||||
|
|
||||
|
## Strawberry کے ساتھ GraphQL { #graphql-with-strawberry } |
||||
|
|
||||
|
اگر آپ کو **GraphQL** کے ساتھ کام کرنے کی ضرورت ہے یا آپ چاہتے ہیں، تو [**Strawberry**](https://strawberry.rocks/) **تجویز کردہ** لائبریری ہے کیونکہ اس کا ڈیزائن **FastAPI** کے ڈیزائن سے سب سے قریب ہے، یہ سب **type annotations** پر مبنی ہے۔ |
||||
|
|
||||
|
آپ کے استعمال کے معاملے کے مطابق، آپ کسی مختلف لائبریری کو ترجیح دے سکتے ہیں، لیکن اگر آپ مجھ سے پوچھیں، تو میں غالباً **Strawberry** آزمانے کا مشورہ دوں گا۔ |
||||
|
|
||||
|
یہاں ایک مختصر جائزہ ہے کہ آپ Strawberry کو FastAPI کے ساتھ کیسے شامل کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/graphql_/tutorial001_py310.py hl[3,22,25] *} |
||||
|
|
||||
|
آپ Strawberry کے بارے میں مزید [Strawberry دستاویزات](https://strawberry.rocks/) میں جان سکتے ہیں۔ |
||||
|
|
||||
|
اور [Strawberry with FastAPI](https://strawberry.rocks/docs/integrations/fastapi) کی دستاویزات بھی دیکھیں۔ |
||||
|
|
||||
|
## Starlette سے پرانا `GraphQLApp` { #older-graphqlapp-from-starlette } |
||||
|
|
||||
|
Starlette کے پچھلے ورژنز میں [Graphene](https://graphene-python.org/) کے ساتھ integration کے لیے `GraphQLApp` class شامل تھی۔ |
||||
|
|
||||
|
اسے Starlette سے deprecated کر دیا گیا تھا، لیکن اگر آپ کے پاس ایسا کوڈ ہے جو اسے استعمال کرتا تھا، تو آپ آسانی سے [starlette-graphene3](https://github.com/ciscorn/starlette-graphene3) پر **منتقل** ہو سکتے ہیں، جو وہی استعمال کے معاملے کا احاطہ کرتا ہے اور **تقریباً ایک جیسا interface** رکھتا ہے۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
اگر آپ کو GraphQL کی ضرورت ہے، تو میں پھر بھی تجویز کروں گا کہ آپ [Strawberry](https://strawberry.rocks/) دیکھیں، کیونکہ یہ custom classes اور types کی بجائے type annotations پر مبنی ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## مزید جانیں { #learn-more } |
||||
|
|
||||
|
آپ **GraphQL** کے بارے میں مزید [GraphQL کی سرکاری دستاویزات](https://graphql.org/) میں جان سکتے ہیں۔ |
||||
|
|
||||
|
آپ اوپر بیان کردہ ہر لائبریری کے بارے میں ان کے لنکس میں مزید پڑھ سکتے ہیں۔ |
||||
@ -0,0 +1,13 @@ |
|||||
|
# طریقہ کار - ترکیبیں { #how-to-recipes } |
||||
|
|
||||
|
یہاں آپ کو **مختلف موضوعات** کے لیے مختلف ترکیبیں یا "طریقہ کار" کی رہنمائیاں ملیں گی۔ |
||||
|
|
||||
|
ان میں سے زیادہ تر خیالات کم و بیش **آزادانہ** ہیں، اور زیادہ تر صورتوں میں آپ کو صرف انہی کا مطالعہ کرنا چاہیے جو براہ راست **آپ کے پروجیکٹ** پر لاگو ہوں۔ |
||||
|
|
||||
|
اگر کوئی چیز آپ کے پروجیکٹ کے لیے دلچسپ اور مفید لگے، تو آگے بڑھیں اور اسے دیکھیں، ورنہ آپ شاید انہیں چھوڑ سکتے ہیں۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
اگر آپ **FastAPI** کو منظم طریقے سے سیکھنا چاہتے ہیں (تجویز کردہ)، تو اس کی بجائے [Tutorial - User Guide](../tutorial/index.md) باب بہ باب پڑھیں۔ |
||||
|
|
||||
|
/// |
||||
@ -0,0 +1,135 @@ |
|||||
|
# Pydantic v1 سے Pydantic v2 میں منتقلی { #migrate-from-pydantic-v1-to-pydantic-v2 } |
||||
|
|
||||
|
اگر آپ کے پاس پرانی FastAPI app ہے، تو آپ شاید Pydantic ورژن 1 استعمال کر رہے ہوں۔ |
||||
|
|
||||
|
FastAPI ورژن 0.100.0 میں Pydantic v1 یا v2 دونوں کی سپورٹ تھی۔ یہ جو بھی آپ نے install کیا ہوتا اسے استعمال کرتا۔ |
||||
|
|
||||
|
FastAPI ورژن 0.119.0 نے Pydantic v2 کے اندر سے Pydantic v1 کی جزوی سپورٹ (`pydantic.v1` کے طور پر) متعارف کرائی، تاکہ v2 میں منتقلی آسان ہو۔ |
||||
|
|
||||
|
FastAPI 0.126.0 نے Pydantic v1 کی سپورٹ ختم کر دی، جبکہ تھوڑی دیر کے لیے `pydantic.v1` کی سپورٹ جاری رکھی۔ |
||||
|
|
||||
|
/// warning | انتباہ |
||||
|
|
||||
|
Pydantic ٹیم نے Python کے تازہ ترین ورژنز کے لیے Pydantic v1 کی سپورٹ بند کر دی ہے، **Python 3.14** سے شروع کرتے ہوئے۔ |
||||
|
|
||||
|
اس میں `pydantic.v1` بھی شامل ہے، جو Python 3.14 اور اس سے اوپر میں مزید سپورٹ نہیں ہے۔ |
||||
|
|
||||
|
اگر آپ Python کی تازہ ترین خصوصیات استعمال کرنا چاہتے ہیں، تو آپ کو یقینی بنانا ہوگا کہ آپ Pydantic v2 استعمال کریں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
اگر آپ کے پاس Pydantic v1 والی پرانی FastAPI app ہے، تو یہاں میں آپ کو دکھاؤں گا کہ اسے Pydantic v2 میں کیسے منتقل کیا جائے، اور **FastAPI 0.119.0 کی خصوصیات** جو بتدریج منتقلی میں مدد کرتی ہیں۔ |
||||
|
|
||||
|
## سرکاری رہنما { #official-guide } |
||||
|
|
||||
|
Pydantic کے پاس v1 سے v2 میں منتقلی کی سرکاری [Migration Guide](https://docs.pydantic.dev/latest/migration/) ہے۔ |
||||
|
|
||||
|
اس میں یہ بھی شامل ہے کہ کیا تبدیل ہوا ہے، validations اب کیسے زیادہ درست اور سخت ہیں، ممکنہ خدشات وغیرہ۔ |
||||
|
|
||||
|
آپ اسے پڑھ کر بہتر سمجھ سکتے ہیں کہ کیا تبدیل ہوا ہے۔ |
||||
|
|
||||
|
## Tests { #tests } |
||||
|
|
||||
|
یقینی بنائیں کہ آپ کی app کے لیے [tests](../tutorial/testing.md) ہیں اور آپ انہیں continuous integration (CI) پر چلاتے ہیں۔ |
||||
|
|
||||
|
اس طرح، آپ اپ گریڈ کر سکتے ہیں اور یقینی بنا سکتے ہیں کہ سب کچھ توقع کے مطابق کام کر رہا ہے۔ |
||||
|
|
||||
|
## `bump-pydantic` { #bump-pydantic } |
||||
|
|
||||
|
بہت سی صورتوں میں، جب آپ بغیر customizations کے عام Pydantic models استعمال کرتے ہیں، تو آپ Pydantic v1 سے Pydantic v2 میں منتقلی کے زیادہ تر عمل کو خودکار بنا سکتے ہیں۔ |
||||
|
|
||||
|
آپ Pydantic ٹیم کا [`bump-pydantic`](https://github.com/pydantic/bump-pydantic) استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
یہ ٹول زیادہ تر کوڈ کو خود بخود تبدیل کرنے میں مدد کرے گا جسے تبدیل کرنے کی ضرورت ہے۔ |
||||
|
|
||||
|
اس کے بعد، آپ tests چلا سکتے ہیں اور جانچ سکتے ہیں کہ سب کچھ کام کرتا ہے۔ اگر کرتا ہے، تو آپ کا کام ہو گیا۔ 😎 |
||||
|
|
||||
|
## Pydantic v2 میں Pydantic v1 { #pydantic-v1-in-v2 } |
||||
|
|
||||
|
Pydantic v2 میں Pydantic v1 کی ہر چیز بطور submodule `pydantic.v1` شامل ہے۔ لیکن یہ Python 3.13 سے اوپر کے ورژنز میں مزید سپورٹ نہیں ہے۔ |
||||
|
|
||||
|
اس کا مطلب ہے کہ آپ Pydantic v2 کا تازہ ترین ورژن install کر سکتے ہیں اور اس submodule سے پرانے Pydantic v1 کے اجزاء import اور استعمال کر سکتے ہیں، جیسے کہ آپ کے پاس پرانا Pydantic v1 install ہو۔ |
||||
|
|
||||
|
{* ../../docs_src/pydantic_v1_in_v2/tutorial001_an_py310.py hl[1,4] *} |
||||
|
|
||||
|
### Pydantic v2 میں Pydantic v1 کے لیے FastAPI سپورٹ { #fastapi-support-for-pydantic-v1-in-v2 } |
||||
|
|
||||
|
FastAPI 0.119.0 سے، Pydantic v2 کے اندر سے Pydantic v1 کی جزوی سپورٹ بھی ہے، تاکہ v2 میں منتقلی آسان ہو۔ |
||||
|
|
||||
|
لہذا، آپ Pydantic کو تازہ ترین ورژن 2 میں اپ گریڈ کر سکتے ہیں، اور `pydantic.v1` submodule استعمال کرنے کے لیے imports تبدیل کر سکتے ہیں، اور بہت سی صورتوں میں یہ بس کام کر جائے گا۔ |
||||
|
|
||||
|
{* ../../docs_src/pydantic_v1_in_v2/tutorial002_an_py310.py hl[2,5,15] *} |
||||
|
|
||||
|
/// warning | انتباہ |
||||
|
|
||||
|
ذہن میں رکھیں کہ چونکہ Pydantic ٹیم Python کے حالیہ ورژنز میں Pydantic v1 کو مزید سپورٹ نہیں کرتی، Python 3.14 سے شروع کرتے ہوئے، `pydantic.v1` کا استعمال بھی Python 3.14 اور اس سے اوپر میں سپورٹ نہیں ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
### ایک ہی app میں Pydantic v1 اور v2 { #pydantic-v1-and-v2-on-the-same-app } |
||||
|
|
||||
|
Pydantic کی طرف سے یہ **سپورٹ نہیں** ہے کہ Pydantic v2 کے model کے اپنے fields بطور Pydantic v1 models defined ہوں یا اس کے برعکس۔ |
||||
|
|
||||
|
```mermaid |
||||
|
graph TB |
||||
|
subgraph "❌ Not Supported" |
||||
|
direction TB |
||||
|
subgraph V2["Pydantic v2 Model"] |
||||
|
V1Field["Pydantic v1 Model"] |
||||
|
end |
||||
|
subgraph V1["Pydantic v1 Model"] |
||||
|
V2Field["Pydantic v2 Model"] |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
style V2 fill:#f9fff3 |
||||
|
style V1 fill:#fff6f0 |
||||
|
style V1Field fill:#fff6f0 |
||||
|
style V2Field fill:#f9fff3 |
||||
|
``` |
||||
|
|
||||
|
...لیکن، آپ ایک ہی app میں الگ الگ models میں Pydantic v1 اور v2 استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
```mermaid |
||||
|
graph TB |
||||
|
subgraph "✅ Supported" |
||||
|
direction TB |
||||
|
subgraph V2["Pydantic v2 Model"] |
||||
|
V2Field["Pydantic v2 Model"] |
||||
|
end |
||||
|
subgraph V1["Pydantic v1 Model"] |
||||
|
V1Field["Pydantic v1 Model"] |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
style V2 fill:#f9fff3 |
||||
|
style V1 fill:#fff6f0 |
||||
|
style V1Field fill:#fff6f0 |
||||
|
style V2Field fill:#f9fff3 |
||||
|
``` |
||||
|
|
||||
|
بعض صورتوں میں، آپ کی FastAPI app میں ایک ہی **path operation** میں Pydantic v1 اور v2 دونوں models رکھنا بھی ممکن ہے: |
||||
|
|
||||
|
{* ../../docs_src/pydantic_v1_in_v2/tutorial003_an_py310.py hl[2:3,6,12,21:22] *} |
||||
|
|
||||
|
اوپر دی گئی اس مثال میں، input model ایک Pydantic v1 model ہے، اور output model (`response_model=ItemV2` میں defined) ایک Pydantic v2 model ہے۔ |
||||
|
|
||||
|
### Pydantic v1 parameters { #pydantic-v1-parameters } |
||||
|
|
||||
|
اگر آپ کو Pydantic v1 models کے ساتھ FastAPI کے مخصوص ٹولز جیسے `Body`، `Query`، `Form` وغیرہ استعمال کرنے کی ضرورت ہے، تو آپ Pydantic v2 میں منتقلی مکمل ہونے تک انہیں `fastapi.temp_pydantic_v1_params` سے import کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/pydantic_v1_in_v2/tutorial004_an_py310.py hl[4,18] *} |
||||
|
|
||||
|
### مراحل میں منتقلی { #migrate-in-steps } |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
پہلے `bump-pydantic` آزمائیں، اگر آپ کے tests پاس ہو جائیں اور یہ کام کر جائے، تو آپ کا کام ایک command میں ہو گیا۔ ✨ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
اگر `bump-pydantic` آپ کے استعمال کے لیے کام نہیں کرتا، تو آپ ایک ہی app میں Pydantic v1 اور v2 دونوں models کی سپورٹ استعمال کر کے بتدریج Pydantic v2 میں منتقلی کر سکتے ہیں۔ |
||||
|
|
||||
|
آپ پہلے Pydantic کو تازہ ترین ورژن 2 میں اپ گریڈ کر سکتے ہیں، اور اپنے تمام models کے لیے `pydantic.v1` استعمال کرنے کے لیے imports تبدیل کر سکتے ہیں۔ |
||||
|
|
||||
|
پھر، آپ اپنے models کو بتدریج گروپس میں Pydantic v1 سے v2 میں منتقل کرنا شروع کر سکتے ہیں۔ 🚶 |
||||
@ -0,0 +1,102 @@ |
|||||
|
# Input اور Output کے لیے الگ OpenAPI Schemas یا نہیں { #separate-openapi-schemas-for-input-and-output-or-not } |
||||
|
|
||||
|
**Pydantic v2** کی ریلیز کے بعد سے، تیار کردہ OpenAPI پہلے سے کچھ زیادہ درست اور **صحیح** ہے۔ 😎 |
||||
|
|
||||
|
درحقیقت، بعض صورتوں میں، ایک ہی Pydantic model کے لیے OpenAPI میں **دو JSON Schemas** ہوں گے، input اور output کے لیے، اس بات پر منحصر ہے کہ آیا ان میں **default values** ہیں۔ |
||||
|
|
||||
|
آئیے دیکھتے ہیں کہ یہ کیسے کام کرتا ہے اور اگر آپ کو ضرورت ہو تو اسے کیسے تبدیل کیا جائے۔ |
||||
|
|
||||
|
## Input اور Output کے لیے Pydantic Models { #pydantic-models-for-input-and-output } |
||||
|
|
||||
|
فرض کریں کہ آپ کے پاس default values کے ساتھ ایک Pydantic model ہے، جیسے یہ: |
||||
|
|
||||
|
{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:7] hl[7] *} |
||||
|
|
||||
|
### Input کے لیے Model { #model-for-input } |
||||
|
|
||||
|
اگر آپ اس model کو اس طرح input کے طور پر استعمال کرتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:15] hl[14] *} |
||||
|
|
||||
|
...تو `description` field **ضروری نہیں** ہوگا۔ کیونکہ اس کی default value `None` ہے۔ |
||||
|
|
||||
|
### Docs میں Input Model { #input-model-in-docs } |
||||
|
|
||||
|
آپ docs میں تصدیق کر سکتے ہیں، `description` field پر **سرخ ستارہ** نہیں ہے، اسے ضروری نشان زد نہیں کیا گیا: |
||||
|
|
||||
|
<div class="screenshot"> |
||||
|
<img src="/img/tutorial/separate-openapi-schemas/image01.png"> |
||||
|
</div> |
||||
|
|
||||
|
### Output کے لیے Model { #model-for-output } |
||||
|
|
||||
|
لیکن اگر آپ وہی model output کے طور پر استعمال کرتے ہیں، جیسے یہاں: |
||||
|
|
||||
|
{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py hl[19] *} |
||||
|
|
||||
|
...تو چونکہ `description` کی default value ہے، اگر آپ اس field کے لیے **کچھ واپس نہیں کرتے**، تو اس میں پھر بھی وہ **default value** ہوگی۔ |
||||
|
|
||||
|
### Output Response ڈیٹا کے لیے Model { #model-for-output-response-data } |
||||
|
|
||||
|
اگر آپ docs کے ساتھ تعامل کریں اور response چیک کریں، حالانکہ کوڈ نے `description` fields میں سے کسی ایک میں کچھ نہیں ڈالا، JSON response میں default value (`null`) موجود ہے: |
||||
|
|
||||
|
<div class="screenshot"> |
||||
|
<img src="/img/tutorial/separate-openapi-schemas/image02.png"> |
||||
|
</div> |
||||
|
|
||||
|
اس کا مطلب ہے کہ اس میں **ہمیشہ ایک قدر** ہوگی، بس بعض اوقات قدر `None` (یا JSON میں `null`) ہو سکتی ہے۔ |
||||
|
|
||||
|
اس کا مطلب ہے کہ، آپ کی API استعمال کرنے والے clients کو یہ جانچنے کی ضرورت نہیں کہ قدر موجود ہے یا نہیں، وہ **فرض کر سکتے ہیں کہ field ہمیشہ موجود رہے گا**، بس بعض صورتوں میں اس کی default value `None` ہوگی۔ |
||||
|
|
||||
|
OpenAPI میں اس کی وضاحت کا طریقہ یہ ہے کہ اس field کو **ضروری** نشان زد کیا جائے، کیونکہ یہ ہمیشہ موجود رہے گا۔ |
||||
|
|
||||
|
اس وجہ سے، کسی model کا JSON Schema اس بات پر منحصر ہو کر مختلف ہو سکتا ہے کہ یہ **input یا output** کے لیے استعمال ہو رہا ہے: |
||||
|
|
||||
|
* **input** کے لیے `description` **ضروری نہیں** ہوگا |
||||
|
* **output** کے لیے یہ **ضروری** ہوگا (اور ممکنہ طور پر `None` ہو، یا JSON کی اصطلاح میں `null`) |
||||
|
|
||||
|
### Docs میں Output کے لیے Model { #model-for-output-in-docs } |
||||
|
|
||||
|
آپ docs میں output model بھی چیک کر سکتے ہیں، `name` اور `description` **دونوں** **سرخ ستارے** کے ساتھ **ضروری** نشان زد ہیں: |
||||
|
|
||||
|
<div class="screenshot"> |
||||
|
<img src="/img/tutorial/separate-openapi-schemas/image03.png"> |
||||
|
</div> |
||||
|
|
||||
|
### Docs میں Input اور Output کے لیے Model { #model-for-input-and-output-in-docs } |
||||
|
|
||||
|
اور اگر آپ OpenAPI میں تمام دستیاب Schemas (JSON Schemas) چیک کریں، تو آپ دیکھیں گے کہ دو ہیں، ایک `Item-Input` اور ایک `Item-Output`۔ |
||||
|
|
||||
|
`Item-Input` کے لیے، `description` **ضروری نہیں** ہے، اس پر سرخ ستارہ نہیں ہے۔ |
||||
|
|
||||
|
لیکن `Item-Output` کے لیے، `description` **ضروری** ہے، اس پر سرخ ستارہ ہے۔ |
||||
|
|
||||
|
<div class="screenshot"> |
||||
|
<img src="/img/tutorial/separate-openapi-schemas/image04.png"> |
||||
|
</div> |
||||
|
|
||||
|
**Pydantic v2** کی اس خصوصیت کے ساتھ، آپ کی API documentation زیادہ **درست** ہے، اور اگر آپ کے پاس خود کار طریقے سے تیار کردہ clients اور SDKs ہیں، تو وہ بھی زیادہ درست ہوں گے، بہتر **developer experience** اور consistency کے ساتھ۔ 🎉 |
||||
|
|
||||
|
## Schemas کو الگ نہ کریں { #do-not-separate-schemas } |
||||
|
|
||||
|
اب، کچھ ایسے معاملات ہیں جہاں آپ input اور output کے لیے **ایک ہی schema** رکھنا چاہ سکتے ہیں۔ |
||||
|
|
||||
|
شاید اس کا سب سے اہم استعمال یہ ہے کہ اگر آپ کے پاس پہلے سے کچھ خود کار طریقے سے تیار کردہ client کوڈ/SDKs ہیں اور آپ ابھی تمام خود کار تیار کردہ client کوڈ/SDKs کو اپ ڈیٹ نہیں کرنا چاہتے، آپ شاید کسی وقت یہ کرنا چاہیں گے، لیکن شاید ابھی نہیں۔ |
||||
|
|
||||
|
اس صورت میں، آپ **FastAPI** میں یہ خصوصیت `separate_input_output_schemas=False` parameter کے ساتھ غیر فعال کر سکتے ہیں۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
`separate_input_output_schemas` کی سپورٹ FastAPI `0.102.0` میں شامل کی گئی تھی۔ 🤓 |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
{* ../../docs_src/separate_openapi_schemas/tutorial002_py310.py hl[10] *} |
||||
|
|
||||
|
### Docs میں Input اور Output Models کے لیے ایک ہی Schema { #same-schema-for-input-and-output-models-in-docs } |
||||
|
|
||||
|
اور اب input اور output کے لیے model کا ایک ہی schema ہوگا، صرف `Item`، اور اس میں `description` **ضروری نہیں** ہوگا: |
||||
|
|
||||
|
<div class="screenshot"> |
||||
|
<img src="/img/tutorial/separate-openapi-schemas/image05.png"> |
||||
|
</div> |
||||
@ -0,0 +1,7 @@ |
|||||
|
# Database کی جانچ { #testing-a-database } |
||||
|
|
||||
|
آپ databases، SQL، اور SQLModel کے بارے میں [SQLModel دستاویزات](https://sqlmodel.tiangolo.com/) میں پڑھ سکتے ہیں۔ 🤓 |
||||
|
|
||||
|
FastAPI کے ساتھ [SQLModel استعمال کرنے کا ایک مختصر tutorial](https://sqlmodel.tiangolo.com/tutorial/fastapi/) موجود ہے۔ ✨ |
||||
|
|
||||
|
اس tutorial میں [SQL databases کی جانچ](https://sqlmodel.tiangolo.com/tutorial/fastapi/tests/) کا ایک حصہ بھی شامل ہے۔ 😎 |
||||
@ -0,0 +1,545 @@ |
|||||
|
# FastAPI { #fastapi } |
||||
|
|
||||
|
<style> |
||||
|
.md-content .md-typeset h1 { display: none; } |
||||
|
</style> |
||||
|
|
||||
|
<p align="center"> |
||||
|
<a href="https://fastapi.tiangolo.com"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a> |
||||
|
</p> |
||||
|
<p align="center"> |
||||
|
<em>FastAPI framework، اعلیٰ کارکردگی، سیکھنے میں آسان، تیز کوڈنگ، پروڈکشن کے لیے تیار</em> |
||||
|
</p> |
||||
|
<p align="center"> |
||||
|
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster"> |
||||
|
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test"> |
||||
|
</a> |
||||
|
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi"> |
||||
|
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage"> |
||||
|
</a> |
||||
|
<a href="https://pypi.org/project/fastapi"> |
||||
|
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version"> |
||||
|
</a> |
||||
|
<a href="https://pypi.org/project/fastapi"> |
||||
|
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Supported Python versions"> |
||||
|
</a> |
||||
|
</p> |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
**دستاویزات**: [https://fastapi.tiangolo.com](https://fastapi.tiangolo.com) |
||||
|
|
||||
|
**سورس کوڈ**: [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi) |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
FastAPI ایک جدید، تیز رفتار (اعلیٰ کارکردگی والا) web framework ہے جو معیاری Python type hints کی بنیاد پر Python کے ساتھ APIs بنانے کے لیے بنایا گیا ہے۔ |
||||
|
|
||||
|
اہم خصوصیات یہ ہیں: |
||||
|
|
||||
|
* **تیز**: بہت اعلیٰ کارکردگی، **NodeJS** اور **Go** کے برابر (Starlette اور Pydantic کی بدولت)۔ [دستیاب تیز ترین Python frameworks میں سے ایک](#performance)۔ |
||||
|
* **تیز کوڈنگ**: فیچرز بنانے کی رفتار تقریباً 200% سے 300% بڑھائیں۔ * |
||||
|
* **کم غلطیاں**: انسانی (ڈویلپر) غلطیوں میں تقریباً 40% کمی۔ * |
||||
|
* **بدیہی**: بہترین ایڈیٹر سپورٹ۔ ہر جگہ <dfn title="also known as auto-complete, autocompletion, IntelliSense">Completion</dfn>۔ debugging میں کم وقت۔ |
||||
|
* **آسان**: استعمال اور سیکھنے میں آسان بنایا گیا ہے۔ دستاویزات پڑھنے میں کم وقت۔ |
||||
|
* **مختصر**: code کی تکرار کم سے کم۔ ہر parameter کے اعلان سے متعدد خصوصیات۔ کم غلطیاں۔ |
||||
|
* **مضبوط**: پروڈکشن کے لیے تیار code حاصل کریں۔ خودکار تعاملی دستاویزات کے ساتھ۔ |
||||
|
* **معیارات پر مبنی**: APIs کے کھلے معیارات پر مبنی (اور مکمل طور پر ہم آہنگ): [OpenAPI](https://github.com/OAI/OpenAPI-Specification) (پہلے Swagger کے نام سے جانا جاتا تھا) اور [JSON Schema](https://json-schema.org/)۔ |
||||
|
|
||||
|
<small>* اندرونی ترقیاتی ٹیم کے ذریعے پروڈکشن ایپلیکیشنز بناتے ہوئے کیے گئے ٹیسٹس پر مبنی تخمینہ۔</small> |
||||
|
|
||||
|
## سپانسرز { #sponsors } |
||||
|
|
||||
|
<!-- sponsors --> |
||||
|
|
||||
|
### کلیدی سپانسر { #keystone-sponsor } |
||||
|
|
||||
|
{% for sponsor in sponsors.keystone -%} |
||||
|
<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a> |
||||
|
{% endfor -%} |
||||
|
|
||||
|
### گولڈ اور سلور سپانسرز { #gold-and-silver-sponsors } |
||||
|
|
||||
|
{% for sponsor in sponsors.gold -%} |
||||
|
<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a> |
||||
|
{% endfor -%} |
||||
|
{%- for sponsor in sponsors.silver -%} |
||||
|
<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a> |
||||
|
{% endfor %} |
||||
|
|
||||
|
<!-- /sponsors --> |
||||
|
|
||||
|
[دیگر سپانسرز](https://fastapi.tiangolo.com/fastapi-people/#sponsors) |
||||
|
|
||||
|
## آراء { #opinions } |
||||
|
|
||||
|
"_[...] میں ان دنوں **FastAPI** بہت زیادہ استعمال کر رہا ہوں۔ [...] میں دراصل اسے اپنی ٹیم کی **Microsoft میں تمام ML services** کے لیے استعمال کرنے کا ارادہ رکھتا ہوں۔ ان میں سے کچھ بنیادی **Windows** پروڈکٹ اور کچھ **Office** پروڈکٹس میں شامل ہو رہی ہیں۔_" |
||||
|
|
||||
|
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26"><small>(ref)</small></a></div> |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
"_ہم نے **FastAPI** لائبریری اپنائی تاکہ ایک **REST** server بنایا جا سکے جس سے **predictions** حاصل کی جا سکیں۔ [Ludwig کے لیے]_" |
||||
|
|
||||
|
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/"><small>(ref)</small></a></div> |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
"_**Netflix** اپنے **بحران کے انتظام** کے آرکیسٹریشن framework: **Dispatch** کی اوپن سورس ریلیز کا اعلان کرتے ہوئے خوش ہے! [**FastAPI** سے بنایا گیا]_" |
||||
|
|
||||
|
<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072"><small>(ref)</small></a></div> |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
"_میں **FastAPI** سے بے حد خوش ہوں۔ یہ بہت مزے کا ہے!_" |
||||
|
|
||||
|
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855">Python Bytes</a> podcast host</strong> <a href="https://x.com/brianokken/status/1112220079972728832"><small>(ref)</small></a></div> |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
"_سچ میں، جو آپ نے بنایا ہے وہ بہت مضبوط اور چمکدار لگتا ہے۔ کئی طرح سے، یہ وہی ہے جو میں **Hug** کو بنانا چاہتا تھا - کسی کو یہ بناتے دیکھنا واقعی حوصلہ افزا ہے۔_" |
||||
|
|
||||
|
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug">Hug</a> کے خالق</strong> <a href="https://news.ycombinator.com/item?id=19455465"><small>(ref)</small></a></div> |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
"_اگر آپ REST APIs بنانے کے لیے ایک **جدید framework** سیکھنا چاہتے ہیں، تو **FastAPI** دیکھیں [...] یہ تیز، استعمال میں آسان اور سیکھنے میں آسان ہے [...]_" |
||||
|
|
||||
|
"_ہم نے اپنی **APIs** کے لیے **FastAPI** اپنا لیا ہے [...] مجھے لگتا ہے آپ کو یہ پسند آئے گا [...]_" |
||||
|
|
||||
|
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai">Explosion AI</a> بانی - <a href="https://spacy.io">spaCy</a> تخلیق کار</strong> <a href="https://x.com/_inesmontani/status/1144173225322143744"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680"><small>(ref)</small></a></div> |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
"_اگر کوئی پروڈکشن Python API بنانا چاہتا ہے، تو میں **FastAPI** کی بہت سفارش کروں گا۔ یہ **خوبصورتی سے ڈیزائن کیا گیا** ہے، **استعمال میں آسان** اور **انتہائی قابل توسیع** ہے، یہ ہماری API first ترقیاتی حکمت عملی کا **اہم جزو** بن گیا ہے اور بہت سی automations اور services جیسے ہمارا Virtual TAC Engineer چلا رہا ہے۔_" |
||||
|
|
||||
|
<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/"><small>(ref)</small></a></div> |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
## FastAPI مختصر دستاویزی فلم { #fastapi-mini-documentary } |
||||
|
|
||||
|
2025 کے آخر میں ریلیز ہونے والی [FastAPI مختصر دستاویزی فلم](https://www.youtube.com/watch?v=mpR8ngthqiE) ہے، آپ اسے آن لائن دیکھ سکتے ہیں: |
||||
|
|
||||
|
<a href="https://www.youtube.com/watch?v=mpR8ngthqiE"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a> |
||||
|
|
||||
|
## **Typer**، CLIs کا FastAPI { #typer-the-fastapi-of-clis } |
||||
|
|
||||
|
<a href="https://typer.tiangolo.com"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a> |
||||
|
|
||||
|
اگر آپ web API کے بجائے ٹرمینل میں استعمال ہونے والی <abbr title="Command Line Interface">CLI</abbr> ایپ بنا رہے ہیں، تو [**Typer**](https://typer.tiangolo.com/) دیکھیں۔ |
||||
|
|
||||
|
**Typer** FastAPI کا چھوٹا بھائی ہے۔ اور اس کا مقصد **CLIs کا FastAPI** بننا ہے۔ ⌨️ 🚀 |
||||
|
|
||||
|
## تقاضے { #requirements } |
||||
|
|
||||
|
FastAPI دیو ہیکل ہستیوں کے کندھوں پر کھڑا ہے: |
||||
|
|
||||
|
* ویب حصوں کے لیے [Starlette](https://www.starlette.dev/)۔ |
||||
|
* ڈیٹا حصوں کے لیے [Pydantic](https://docs.pydantic.dev/)۔ |
||||
|
|
||||
|
## انسٹالیشن { #installation } |
||||
|
|
||||
|
ایک [virtual environment](https://fastapi.tiangolo.com/virtual-environments/) بنائیں اور فعال کریں اور پھر FastAPI انسٹال کریں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ pip install "fastapi[standard]" |
||||
|
|
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
**نوٹ**: یقینی بنائیں کہ آپ `"fastapi[standard]"` کو quotes میں لکھیں تاکہ یہ تمام ٹرمینلز میں کام کرے۔ |
||||
|
|
||||
|
## مثال { #example } |
||||
|
|
||||
|
### بنائیں { #create-it } |
||||
|
|
||||
|
ایک فائل `main.py` بنائیں: |
||||
|
|
||||
|
```Python |
||||
|
from fastapi import FastAPI |
||||
|
|
||||
|
app = FastAPI() |
||||
|
|
||||
|
|
||||
|
@app.get("/") |
||||
|
def read_root(): |
||||
|
return {"Hello": "World"} |
||||
|
|
||||
|
|
||||
|
@app.get("/items/{item_id}") |
||||
|
def read_item(item_id: int, q: str | None = None): |
||||
|
return {"item_id": item_id, "q": q} |
||||
|
``` |
||||
|
|
||||
|
<details markdown="1"> |
||||
|
<summary>یا <code>async def</code> استعمال کریں...</summary> |
||||
|
|
||||
|
اگر آپ کا code `async` / `await` استعمال کرتا ہے، تو `async def` استعمال کریں: |
||||
|
|
||||
|
```Python hl_lines="7 12" |
||||
|
from fastapi import FastAPI |
||||
|
|
||||
|
app = FastAPI() |
||||
|
|
||||
|
|
||||
|
@app.get("/") |
||||
|
async def read_root(): |
||||
|
return {"Hello": "World"} |
||||
|
|
||||
|
|
||||
|
@app.get("/items/{item_id}") |
||||
|
async def read_item(item_id: int, q: str | None = None): |
||||
|
return {"item_id": item_id, "q": q} |
||||
|
``` |
||||
|
|
||||
|
**نوٹ**: |
||||
|
|
||||
|
اگر آپ نہیں جانتے، تو دستاویزات میں [`async` اور `await`](https://fastapi.tiangolo.com/async/#in-a-hurry) کے بارے میں _"جلدی میں ہیں؟"_ سیکشن دیکھیں۔ |
||||
|
|
||||
|
</details> |
||||
|
|
||||
|
### چلائیں { #run-it } |
||||
|
|
||||
|
server کو اس کمانڈ سے چلائیں: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ fastapi dev |
||||
|
|
||||
|
╭────────── FastAPI CLI - Development mode ───────────╮ |
||||
|
│ │ |
||||
|
│ Serving at: http://127.0.0.1:8000 │ |
||||
|
│ │ |
||||
|
│ API docs: http://127.0.0.1:8000/docs │ |
||||
|
│ │ |
||||
|
│ Running in development mode, for production use: │ |
||||
|
│ │ |
||||
|
│ fastapi run │ |
||||
|
│ │ |
||||
|
╰─────────────────────────────────────────────────────╯ |
||||
|
|
||||
|
INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp'] |
||||
|
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
||||
|
INFO: Started reloader process [2248755] using WatchFiles |
||||
|
INFO: Started server process [2248757] |
||||
|
INFO: Waiting for application startup. |
||||
|
INFO: Application startup complete. |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<details markdown="1"> |
||||
|
<summary><code>fastapi dev</code> کمانڈ کے بارے میں...</summary> |
||||
|
|
||||
|
`fastapi dev` کمانڈ خودکار طور پر آپ کی `main.py` فائل پڑھتی ہے، اس میں **FastAPI** ایپ تلاش کرتی ہے، اور [Uvicorn](https://www.uvicorn.dev) استعمال کر کے server شروع کرتی ہے۔ |
||||
|
|
||||
|
بطور ڈیفالٹ، `fastapi dev` مقامی ترقی کے لیے auto-reload فعال کر کے شروع ہوگا۔ |
||||
|
|
||||
|
آپ اس کے بارے میں [FastAPI CLI دستاویزات](https://fastapi.tiangolo.com/fastapi-cli/) میں مزید پڑھ سکتے ہیں۔ |
||||
|
|
||||
|
</details> |
||||
|
|
||||
|
### دیکھیں { #check-it } |
||||
|
|
||||
|
اپنا براؤزر [http://127.0.0.1:8000/items/5?q=somequery](http://127.0.0.1:8000/items/5?q=somequery) پر کھولیں۔ |
||||
|
|
||||
|
آپ کو JSON response اس طرح نظر آئے گا: |
||||
|
|
||||
|
```JSON |
||||
|
{"item_id": 5, "q": "somequery"} |
||||
|
``` |
||||
|
|
||||
|
آپ نے پہلے ہی ایک API بنا لیا ہے جو: |
||||
|
|
||||
|
* _paths_ `/` اور `/items/{item_id}` پر HTTP requests وصول کرتا ہے۔ |
||||
|
* دونوں _paths_ `GET` <em>operations</em> (جنہیں HTTP _methods_ بھی کہا جاتا ہے) لیتے ہیں۔ |
||||
|
* _path_ `/items/{item_id}` میں ایک _path parameter_ `item_id` ہے جو `int` ہونا چاہیے۔ |
||||
|
* _path_ `/items/{item_id}` میں ایک اختیاری `str` _query parameter_ `q` ہے۔ |
||||
|
|
||||
|
### تعاملی API دستاویزات { #interactive-api-docs } |
||||
|
|
||||
|
اب [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) پر جائیں۔ |
||||
|
|
||||
|
آپ کو خودکار تعاملی API دستاویزات نظر آئیں گی ([Swagger UI](https://github.com/swagger-api/swagger-ui) کی فراہم کردہ): |
||||
|
|
||||
|
 |
||||
|
|
||||
|
### متبادل API دستاویزات { #alternative-api-docs } |
||||
|
|
||||
|
اور اب، [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc) پر جائیں۔ |
||||
|
|
||||
|
آپ کو متبادل خودکار دستاویزات نظر آئیں گی ([ReDoc](https://github.com/Rebilly/ReDoc) کی فراہم کردہ): |
||||
|
|
||||
|
 |
||||
|
|
||||
|
## مثال کی اپ گریڈ { #example-upgrade } |
||||
|
|
||||
|
اب فائل `main.py` میں ترمیم کریں تاکہ `PUT` request سے body وصول کیا جا سکے۔ |
||||
|
|
||||
|
Pydantic کی بدولت معیاری Python types استعمال کر کے body بیان کریں۔ |
||||
|
|
||||
|
```Python hl_lines="2 7-10 23-25" |
||||
|
from fastapi import FastAPI |
||||
|
from pydantic import BaseModel |
||||
|
|
||||
|
app = FastAPI() |
||||
|
|
||||
|
|
||||
|
class Item(BaseModel): |
||||
|
name: str |
||||
|
price: float |
||||
|
is_offer: bool | None = None |
||||
|
|
||||
|
|
||||
|
@app.get("/") |
||||
|
def read_root(): |
||||
|
return {"Hello": "World"} |
||||
|
|
||||
|
|
||||
|
@app.get("/items/{item_id}") |
||||
|
def read_item(item_id: int, q: str | None = None): |
||||
|
return {"item_id": item_id, "q": q} |
||||
|
|
||||
|
|
||||
|
@app.put("/items/{item_id}") |
||||
|
def update_item(item_id: int, item: Item): |
||||
|
return {"item_name": item.name, "item_id": item_id} |
||||
|
``` |
||||
|
|
||||
|
`fastapi dev` server خودکار طور پر reload ہو جائے گا۔ |
||||
|
|
||||
|
### تعاملی API دستاویزات کی اپ گریڈ { #interactive-api-docs-upgrade } |
||||
|
|
||||
|
اب [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) پر جائیں۔ |
||||
|
|
||||
|
* تعاملی API دستاویزات خودکار طور پر اپ ڈیٹ ہو جائیں گی، نئی body سمیت: |
||||
|
|
||||
|
 |
||||
|
|
||||
|
* "Try it out" بٹن پر کلک کریں، یہ آپ کو parameters بھرنے اور API کے ساتھ براہ راست تعامل کرنے کی اجازت دیتا ہے: |
||||
|
|
||||
|
 |
||||
|
|
||||
|
* پھر "Execute" بٹن پر کلک کریں، یوزر انٹرفیس آپ کی API سے بات کرے گا، parameters بھیجے گا، نتائج حاصل کرے گا اور انہیں اسکرین پر دکھائے گا: |
||||
|
|
||||
|
 |
||||
|
|
||||
|
### متبادل API دستاویزات کی اپ گریڈ { #alternative-api-docs-upgrade } |
||||
|
|
||||
|
اور اب، [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc) پر جائیں۔ |
||||
|
|
||||
|
* متبادل دستاویزات بھی نئے query parameter اور body کی عکاسی کریں گی: |
||||
|
|
||||
|
 |
||||
|
|
||||
|
### خلاصہ { #recap } |
||||
|
|
||||
|
خلاصہ یہ کہ، آپ parameters، body وغیرہ کی types **ایک بار** function parameters کے طور پر بیان کرتے ہیں۔ |
||||
|
|
||||
|
آپ یہ معیاری جدید Python types کے ساتھ کرتے ہیں۔ |
||||
|
|
||||
|
آپ کو کوئی نئی syntax، کسی مخصوص لائبریری کے methods یا classes سیکھنے کی ضرورت نہیں۔ |
||||
|
|
||||
|
بس معیاری **Python**۔ |
||||
|
|
||||
|
مثال کے طور پر، ایک `int` کے لیے: |
||||
|
|
||||
|
```Python |
||||
|
item_id: int |
||||
|
``` |
||||
|
|
||||
|
یا ایک زیادہ پیچیدہ `Item` model کے لیے: |
||||
|
|
||||
|
```Python |
||||
|
item: Item |
||||
|
``` |
||||
|
|
||||
|
...اور اس ایک اعلان کے ساتھ آپ کو ملتا ہے: |
||||
|
|
||||
|
* ایڈیٹر سپورٹ، بشمول: |
||||
|
* Completion۔ |
||||
|
* Type checks۔ |
||||
|
* ڈیٹا کی توثیق: |
||||
|
* ڈیٹا غلط ہونے پر خودکار اور واضح غلطیاں۔ |
||||
|
* گہرائی سے nested JSON objects کی بھی توثیق۔ |
||||
|
* ان پٹ ڈیٹا کی <dfn title="also known as: serialization, parsing, marshalling">تبدیلی</dfn>: نیٹ ورک سے Python ڈیٹا اور types میں۔ پڑھنا: |
||||
|
* JSON۔ |
||||
|
* Path parameters۔ |
||||
|
* Query parameters۔ |
||||
|
* Cookies۔ |
||||
|
* Headers۔ |
||||
|
* Forms۔ |
||||
|
* Files۔ |
||||
|
* آؤٹ پٹ ڈیٹا کی <dfn title="also known as: serialization, parsing, marshalling">تبدیلی</dfn>: Python ڈیٹا اور types سے نیٹ ورک ڈیٹا (بطور JSON) میں: |
||||
|
* Python types تبدیل کریں (`str`, `int`, `float`, `bool`, `list`, وغیرہ)۔ |
||||
|
* `datetime` objects۔ |
||||
|
* `UUID` objects۔ |
||||
|
* Database models۔ |
||||
|
* ...اور بہت کچھ۔ |
||||
|
* خودکار تعاملی API دستاویزات، بشمول 2 متبادل یوزر انٹرفیسز: |
||||
|
* Swagger UI۔ |
||||
|
* ReDoc۔ |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
پچھلی code مثال کی طرف واپس آتے ہوئے، **FastAPI** یہ کرے گا: |
||||
|
|
||||
|
* `GET` اور `PUT` requests کے لیے path میں `item_id` ہونے کی توثیق کرے گا۔ |
||||
|
* `GET` اور `PUT` requests کے لیے `item_id` کی type `int` ہونے کی توثیق کرے گا۔ |
||||
|
* اگر نہیں ہے، تو client کو ایک مفید، واضح غلطی نظر آئے گی۔ |
||||
|
* `GET` requests کے لیے چیک کرے گا کہ کوئی اختیاری query parameter بنام `q` ہے (جیسا کہ `http://127.0.0.1:8000/items/foo?q=somequery`)۔ |
||||
|
* چونکہ `q` parameter کو `= None` کے ساتھ بیان کیا گیا ہے، اس لیے یہ اختیاری ہے۔ |
||||
|
* `None` کے بغیر یہ لازمی ہوتا (جیسا کہ `PUT` کے معاملے میں body ہے)۔ |
||||
|
* `/items/{item_id}` کے لیے `PUT` requests میں، body کو بطور JSON پڑھے گا: |
||||
|
* چیک کرے گا کہ اس میں لازمی attribute `name` ہے جو `str` ہونا چاہیے۔ |
||||
|
* چیک کرے گا کہ اس میں لازمی attribute `price` ہے جو `float` ہونا ضروری ہے۔ |
||||
|
* چیک کرے گا کہ اس میں اختیاری attribute `is_offer` ہے، جو اگر موجود ہو تو `bool` ہونا چاہیے۔ |
||||
|
* یہ سب گہرائی سے nested JSON objects کے لیے بھی کام کرے گا۔ |
||||
|
* خودکار طور پر JSON سے اور JSON میں تبدیل کرے گا۔ |
||||
|
* OpenAPI کے ساتھ ہر چیز کی دستاویز بنائے گا، جو استعمال ہو سکتی ہے: |
||||
|
* تعاملی دستاویزاتی نظاموں سے۔ |
||||
|
* کئی زبانوں کے لیے خودکار client code generation نظاموں سے۔ |
||||
|
* 2 تعاملی دستاویزاتی ویب انٹرفیسز براہ راست فراہم کرے گا۔ |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
ہم نے ابھی صرف سطح کو چھوا ہے، لیکن آپ کو پہلے سے اندازہ ہو گیا ہے کہ یہ سب کیسے کام کرتا ہے۔ |
||||
|
|
||||
|
اس لائن کو تبدیل کر کے دیکھیں: |
||||
|
|
||||
|
```Python |
||||
|
return {"item_name": item.name, "item_id": item_id} |
||||
|
``` |
||||
|
|
||||
|
...اس سے: |
||||
|
|
||||
|
```Python |
||||
|
... "item_name": item.name ... |
||||
|
``` |
||||
|
|
||||
|
...اس میں: |
||||
|
|
||||
|
```Python |
||||
|
... "item_price": item.price ... |
||||
|
``` |
||||
|
|
||||
|
...اور دیکھیں کہ آپ کا ایڈیٹر attributes کو خود مکمل کرے گا اور ان کی types جانے گا: |
||||
|
|
||||
|
 |
||||
|
|
||||
|
مزید خصوصیات سمیت ایک زیادہ مکمل مثال کے لیے، <a href="https://fastapi.tiangolo.com/tutorial/">Tutorial - User Guide</a> دیکھیں۔ |
||||
|
|
||||
|
**اسپائلر الرٹ**: tutorial - user guide میں شامل ہے: |
||||
|
|
||||
|
* مختلف جگہوں سے **parameters** کا اعلان جیسے: **headers**، **cookies**، **form fields** اور **files**۔ |
||||
|
* `maximum_length` یا `regex` جیسی **توثیقی حدود** مقرر کرنے کا طریقہ۔ |
||||
|
* ایک بہت طاقتور اور استعمال میں آسان **<dfn title="also known as components, resources, providers, services, injectables">Dependency Injection</dfn>** سسٹم۔ |
||||
|
* سیکیورٹی اور تصدیق، بشمول **OAuth2** بمع **JWT tokens** اور **HTTP Basic** auth کی سپورٹ۔ |
||||
|
* **گہرائی سے nested JSON models** بیان کرنے کی مزید ایڈوانسڈ (لیکن اتنی ہی آسان) تکنیکیں (Pydantic کی بدولت)۔ |
||||
|
* [Strawberry](https://strawberry.rocks) اور دیگر لائبریریز کے ساتھ **GraphQL** انضمام۔ |
||||
|
* (Starlette کی بدولت) بہت سی اضافی خصوصیات جیسے: |
||||
|
* **WebSockets** |
||||
|
* HTTPX اور `pytest` پر مبنی انتہائی آسان ٹیسٹس |
||||
|
* **CORS** |
||||
|
* **Cookie Sessions** |
||||
|
* ...اور مزید۔ |
||||
|
|
||||
|
### اپنی ایپ deploy کریں (اختیاری) { #deploy-your-app-optional } |
||||
|
|
||||
|
آپ اختیاری طور پر اپنی FastAPI ایپ کو [FastAPI Cloud](https://fastapicloud.com) پر deploy کر سکتے ہیں، اگر ابھی تک نہیں کیا تو ویٹنگ لسٹ میں شامل ہو جائیں۔ 🚀 |
||||
|
|
||||
|
اگر آپ کے پاس پہلے سے **FastAPI Cloud** اکاؤنٹ ہے (ہم نے آپ کو ویٹنگ لسٹ سے مدعو کیا تھا 😉)، تو آپ ایک کمانڈ سے اپنی ایپلیکیشن deploy کر سکتے ہیں۔ |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ fastapi deploy |
||||
|
|
||||
|
Deploying to FastAPI Cloud... |
||||
|
|
||||
|
✅ Deployment successful! |
||||
|
|
||||
|
🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
بس! اب آپ اس URL پر اپنی ایپ تک رسائی حاصل کر سکتے ہیں۔ ✨ |
||||
|
|
||||
|
#### FastAPI Cloud کے بارے میں { #about-fastapi-cloud } |
||||
|
|
||||
|
**[FastAPI Cloud](https://fastapicloud.com)** وہی مصنف اور ٹیم بنا رہی ہے جو **FastAPI** کے پیچھے ہے۔ |
||||
|
|
||||
|
یہ کم سے کم محنت کے ساتھ API **بنانے**، **deploy کرنے**، اور **تک رسائی** حاصل کرنے کے عمل کو آسان بناتا ہے۔ |
||||
|
|
||||
|
یہ FastAPI کے ساتھ ایپس بنانے کا وہی **ڈویلپر تجربہ** انہیں کلاؤڈ پر **deploy** کرنے میں لاتا ہے۔ 🎉 |
||||
|
|
||||
|
FastAPI Cloud *FastAPI اور دوستوں* کے اوپن سورس پراجیکٹس کا بنیادی سپانسر اور فنڈنگ فراہم کنندہ ہے۔ ✨ |
||||
|
|
||||
|
#### دوسرے کلاؤڈ فراہم کنندگان پر Deploy کریں { #deploy-to-other-cloud-providers } |
||||
|
|
||||
|
FastAPI اوپن سورس ہے اور معیارات پر مبنی ہے۔ آپ FastAPI ایپس کسی بھی کلاؤڈ فراہم کنندہ پر deploy کر سکتے ہیں جو آپ چاہیں۔ |
||||
|
|
||||
|
اپنے کلاؤڈ فراہم کنندہ کی رہنمائی کے مطابق FastAPI ایپس deploy کریں۔ 🤓 |
||||
|
|
||||
|
## کارکردگی { #performance } |
||||
|
|
||||
|
آزاد TechEmpower بینچ مارکس دکھاتے ہیں کہ Uvicorn کے تحت چلنے والی **FastAPI** ایپلیکیشنز [دستیاب تیز ترین Python frameworks میں سے ایک](https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7) ہیں، صرف Starlette اور خود Uvicorn سے پیچھے ہیں (جو FastAPI اندرونی طور پر استعمال کرتا ہے)۔ (*) |
||||
|
|
||||
|
اس کے بارے میں مزید سمجھنے کے لیے، [بینچ مارکس](https://fastapi.tiangolo.com/benchmarks/) سیکشن دیکھیں۔ |
||||
|
|
||||
|
## Dependencies { #dependencies } |
||||
|
|
||||
|
FastAPI کا انحصار Pydantic اور Starlette پر ہے۔ |
||||
|
|
||||
|
### `standard` Dependencies { #standard-dependencies } |
||||
|
|
||||
|
جب آپ `pip install "fastapi[standard]"` سے FastAPI انسٹال کرتے ہیں تو یہ اختیاری dependencies کے `standard` گروپ کے ساتھ آتا ہے: |
||||
|
|
||||
|
Pydantic کے استعمال کردہ: |
||||
|
|
||||
|
* [`email-validator`](https://github.com/JoshData/python-email-validator) - email کی توثیق کے لیے۔ |
||||
|
|
||||
|
Starlette کے استعمال کردہ: |
||||
|
|
||||
|
* [`httpx`](https://www.python-httpx.org) - اگر آپ `TestClient` استعمال کرنا چاہتے ہیں تو ضروری ہے۔ |
||||
|
* [`jinja2`](https://jinja.palletsprojects.com) - اگر آپ ڈیفالٹ template ترتیب استعمال کرنا چاہتے ہیں تو ضروری ہے۔ |
||||
|
* [`python-multipart`](https://github.com/Kludex/python-multipart) - اگر آپ `request.form()` کے ساتھ form <dfn title="converting the string that comes from an HTTP request into Python data">"parsing"</dfn> کی سپورٹ چاہتے ہیں تو ضروری ہے۔ |
||||
|
|
||||
|
FastAPI کے استعمال کردہ: |
||||
|
|
||||
|
* [`uvicorn`](https://www.uvicorn.dev) - اس server کے لیے جو آپ کی ایپلیکیشن لوڈ اور سرو کرتا ہے۔ اس میں `uvicorn[standard]` شامل ہے، جس میں اعلیٰ کارکردگی سرونگ کے لیے ضروری کچھ dependencies (مثلاً `uvloop`) شامل ہیں۔ |
||||
|
* `fastapi-cli[standard]` - `fastapi` کمانڈ فراہم کرنے کے لیے۔ |
||||
|
* اس میں `fastapi-cloud-cli` شامل ہے، جو آپ کو اپنی FastAPI ایپلیکیشن [FastAPI Cloud](https://fastapicloud.com) پر deploy کرنے کی اجازت دیتا ہے۔ |
||||
|
|
||||
|
### `standard` Dependencies کے بغیر { #without-standard-dependencies } |
||||
|
|
||||
|
اگر آپ `standard` اختیاری dependencies شامل نہیں کرنا چاہتے، تو `pip install "fastapi[standard]"` کے بجائے `pip install fastapi` سے انسٹال کریں۔ |
||||
|
|
||||
|
### `fastapi-cloud-cli` کے بغیر { #without-fastapi-cloud-cli } |
||||
|
|
||||
|
اگر آپ FastAPI معیاری dependencies کے ساتھ انسٹال کرنا چاہتے ہیں لیکن `fastapi-cloud-cli` کے بغیر، تو `pip install "fastapi[standard-no-fastapi-cloud-cli]"` سے انسٹال کریں۔ |
||||
|
|
||||
|
### اضافی اختیاری Dependencies { #additional-optional-dependencies } |
||||
|
|
||||
|
کچھ اضافی dependencies ہیں جو آپ شاید انسٹال کرنا چاہیں۔ |
||||
|
|
||||
|
اضافی اختیاری Pydantic dependencies: |
||||
|
|
||||
|
* [`pydantic-settings`](https://docs.pydantic.dev/latest/usage/pydantic_settings/) - settings management کے لیے۔ |
||||
|
* [`pydantic-extra-types`](https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/) - Pydantic کے ساتھ استعمال کے لیے اضافی types۔ |
||||
|
|
||||
|
اضافی اختیاری FastAPI dependencies: |
||||
|
|
||||
|
* [`orjson`](https://github.com/ijl/orjson) - اگر آپ `ORJSONResponse` استعمال کرنا چاہتے ہیں تو ضروری ہے۔ |
||||
|
* [`ujson`](https://github.com/esnme/ultrajson) - اگر آپ `UJSONResponse` استعمال کرنا چاہتے ہیں تو ضروری ہے۔ |
||||
|
|
||||
|
## لائسنس { #license } |
||||
|
|
||||
|
یہ پراجیکٹ MIT لائسنس کی شرائط کے تحت لائسنس یافتہ ہے۔ |
||||
@ -0,0 +1,5 @@ |
|||||
|
# سیکھیں { #learn } |
||||
|
|
||||
|
یہاں **FastAPI** سیکھنے کے لیے تعارفی حصے اور tutorials موجود ہیں۔ |
||||
|
|
||||
|
آپ اسے ایک **کتاب**، ایک **کورس**، FastAPI سیکھنے کا **سرکاری** اور تجویز کردہ طریقہ سمجھ سکتے ہیں۔ 😎 |
||||
@ -0,0 +1,157 @@ |
|||||
|
# Repository Management Tasks |
||||
|
|
||||
|
یہ وہ کام ہیں جو FastAPI repository کو manage کرنے کے لیے [ٹیم ممبران](./fastapi-people.md#team) انجام دے سکتے ہیں۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
یہ سیکشن صرف مٹھی بھر لوگوں کے لیے مفید ہے، وہ ٹیم ممبران جن کے پاس repository manage کرنے کی اجازتیں ہیں۔ آپ شاید اسے چھوڑ سکتے ہیں۔ 😉 |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
...تو آپ [FastAPI کی ٹیم کے ممبر](./fastapi-people.md#team) ہیں؟ واہ، آپ بہت زبردست ہیں! 😎 |
||||
|
|
||||
|
آپ [FastAPI کی مدد کریں - مدد حاصل کریں](./help-fastapi.md) میں سب کچھ بیرونی شراکت داروں کی طرح مدد کر سکتے ہیں۔ لیکن اس کے علاوہ، کچھ کام ایسے ہیں جو صرف آپ (ٹیم کے حصے کے طور پر) انجام دے سکتے ہیں۔ |
||||
|
|
||||
|
یہاں ان کاموں کی عمومی ہدایات ہیں جو آپ انجام دے سکتے ہیں۔ |
||||
|
|
||||
|
آپ کی مدد کے لیے بہت شکریہ۔ 🙇 |
||||
|
|
||||
|
## مہربان رہیں |
||||
|
|
||||
|
سب سے پہلے، مہربان رہیں۔ 😊 |
||||
|
|
||||
|
اگر آپ ٹیم میں شامل کیے گئے تو شاید آپ بہت مہربان ہیں، لیکن یہ ذکر کرنا ضروری ہے۔ 🤓 |
||||
|
|
||||
|
### جب چیزیں مشکل ہوں |
||||
|
|
||||
|
جب چیزیں اچھی ہوں تو سب کچھ آسان ہوتا ہے، تو اس کے لیے زیادہ ہدایات کی ضرورت نہیں۔ لیکن جب چیزیں مشکل ہوں، یہاں کچھ رہنمائی ہے۔ |
||||
|
|
||||
|
اچھی بات تلاش کرنے کی کوشش کریں۔ عام طور پر، اگر لوگ غیر دوستانہ نہیں ہو رہے، تو ان کی محنت اور دلچسپی کا شکریہ ادا کرنے کی کوشش کریں، چاہے آپ بنیادی موضوع (بحث، PR) سے متفق نہ ہوں، بس project میں دلچسپی لینے، یا کچھ کرنے کی کوشش میں وقت لگانے کا شکریہ ادا کریں۔ |
||||
|
|
||||
|
متن میں جذبات ظاہر کرنا مشکل ہوتا ہے، مدد کے لیے emojis استعمال کریں۔ 😅 |
||||
|
|
||||
|
Discussions اور PRs میں، بہت سے معاملات میں لوگ اپنی پریشانی لاتے ہیں اور بغیر فلٹر کے دکھاتے ہیں، بہت سے معاملات میں مبالغہ آرائی، شکایت، حق جتانا وغیرہ۔ یہ واقعی اچھا نہیں ہے، اور جب ایسا ہوتا ہے تو ان کے مسائل حل کرنے کی ہماری ترجیح کم ہو جاتی ہے۔ لیکن پھر بھی، سانس لینے کی کوشش کریں، اور اپنے جوابات میں نرم رہیں۔ |
||||
|
|
||||
|
تلخ طنز یا ممکنہ طور پر passive-aggressive تبصروں سے بچنے کی کوشش کریں۔ اگر کچھ غلط ہے، تو طنزیہ ہونے سے بہتر ہے کہ براہ راست (نرمی سے) بات کریں۔ |
||||
|
|
||||
|
جتنا ہو سکے مخصوص اور معروضی ہونے کی کوشش کریں، عمومی باتوں سے بچیں۔ |
||||
|
|
||||
|
ان گفتگو کے لیے جو زیادہ مشکل ہوں، مثلاً PR مسترد کرنا، آپ مجھ سے (@tiangolo) براہ راست سنبھالنے کو کہہ سکتے ہیں۔ |
||||
|
|
||||
|
## PR Titles ترمیم کریں |
||||
|
|
||||
|
* PR title ترمیم کریں تاکہ یہ [gitmoji](https://gitmoji.dev/) سے emoji کے ساتھ شروع ہو۔ |
||||
|
* Emoji character استعمال کریں، GitHub code نہیں۔ تو `🐛` استعمال کریں `:bug:` کی بجائے۔ تاکہ GitHub سے باہر بھی صحیح دکھائی دے، مثلاً release notes میں۔ |
||||
|
* تراجم کے لیے `🌐` emoji ("globe with meridians") استعمال کریں۔ |
||||
|
* Title فعل سے شروع کریں۔ مثلاً `Add`، `Refactor`، `Fix` وغیرہ۔ اس طرح title بتائے گا کہ PR کیا کرتا ہے۔ جیسے `Add support for teleporting`، بجائے `Teleporting wasn't working, so this PR fixes it`۔ |
||||
|
* PR title کا متن "امری" انداز میں ترمیم کریں، جیسے حکم دے رہے ہوں۔ تو `Adding support for teleporting` کی بجائے `Add support for teleporting` استعمال کریں۔ |
||||
|
* Title وضاحتی ہو کہ یہ کیا حاصل کرتا ہے۔ اگر feature ہے تو اسے بیان کرنے کی کوشش کریں، مثلاً `Add support for teleporting` بجائے `Create TeleportAdapter class`۔ |
||||
|
* Title نقطے (`.`) سے ختم نہ کریں۔ |
||||
|
* جب PR ترجمے کے لیے ہو، `🌐` سے شروع کریں اور پھر `Add {language} translation for` اور پھر ترجمہ شدہ فائل کا path۔ مثال کے طور پر: |
||||
|
|
||||
|
```Markdown |
||||
|
🌐 Add Spanish translation for `docs/es/docs/teleporting.md` |
||||
|
``` |
||||
|
|
||||
|
PR merge ہونے کے بعد، ایک GitHub Action ([latest-changes](https://github.com/tiangolo/latest-changes)) خودکار طور پر تازہ ترین تبدیلیاں اپڈیٹ کرنے کے لیے PR title استعمال کرے گی۔ |
||||
|
|
||||
|
تو اچھا PR title ہونا نہ صرف GitHub میں اچھا دکھائے گا، بلکہ release notes میں بھی۔ 📝 |
||||
|
|
||||
|
## PRs میں Labels شامل کریں |
||||
|
|
||||
|
وہی GitHub Action [latest-changes](https://github.com/tiangolo/latest-changes) release notes میں اس PR کو کس سیکشن میں رکھنا ہے یہ فیصلہ کرنے کے لیے PR میں ایک label استعمال کرتی ہے۔ |
||||
|
|
||||
|
یقینی بنائیں کہ آپ [latest-changes labels کی فہرست](https://github.com/tiangolo/latest-changes#using-labels) سے supported label استعمال کریں: |
||||
|
|
||||
|
* `breaking`: Breaking Changes |
||||
|
* موجودہ code ٹوٹ جائے گا اگر وہ اپنا code تبدیل کیے بغیر ورژن اپڈیٹ کریں۔ یہ شاذ و نادر ہوتا ہے، تو یہ label کم استعمال ہوتا ہے۔ |
||||
|
* `security`: Security Fixes |
||||
|
* یہ security fixes کے لیے ہے، جیسے vulnerabilities۔ یہ تقریباً کبھی استعمال نہیں ہوگا۔ |
||||
|
* `feature`: Features |
||||
|
* نئی features، ایسی چیزوں کی سہولت شامل کرنا جو پہلے موجود نہیں تھیں۔ |
||||
|
* `bug`: Fixes |
||||
|
* کوئی چیز جو supported تھی وہ کام نہیں کر رہی تھی، اور یہ اسے ٹھیک کرتا ہے۔ |
||||
|
* `refactor`: Refactors |
||||
|
* یہ عام طور پر اندرونی code میں تبدیلیوں کے لیے ہے جو رویے کو نہیں بدلتیں۔ |
||||
|
* `upgrade`: Upgrades |
||||
|
* یہ project سے براہ راست dependencies کے upgrades کے لیے ہے۔ |
||||
|
* `docs`: Docs |
||||
|
* Docs میں تبدیلیاں۔ اس میں تراجم کی تبدیلیاں شامل نہیں ہیں۔ |
||||
|
* `lang-all`: Translations |
||||
|
* تراجم کے لیے استعمال کریں۔ |
||||
|
* `internal`: Internal |
||||
|
* ایسی تبدیلیوں کے لیے استعمال کریں جو صرف repo management کو متاثر کرتی ہیں۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
Dependabot جیسے tools کچھ labels شامل کریں گے، جیسے `dependencies`، لیکن یاد رکھیں کہ یہ label `latest-changes` GitHub Action استعمال نہیں کرتی، تو release notes میں استعمال نہیں ہوگا۔ براہ کرم یقینی بنائیں کہ اوپر والے labels میں سے ایک شامل ہو۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## ترجمے کی PRs میں Labels شامل کریں |
||||
|
|
||||
|
جب ترجمے کی PR ہو، `lang-all` label کے علاوہ، زبان کے لیے بھی label شامل کریں۔ |
||||
|
|
||||
|
ہر زبان کے لیے زبان code کا استعمال کرتے ہوئے ایک label ہوگا، جیسے `lang-{lang code}`، مثلاً ہسپانوی کے لیے `lang-es`، فرانسیسی کے لیے `lang-fr` وغیرہ۔ |
||||
|
|
||||
|
* مخصوص زبان کا label شامل کریں۔ |
||||
|
* `awaiting-review` label شامل کریں۔ |
||||
|
|
||||
|
`awaiting-review` label خاص ہے، صرف تراجم کے لیے۔ ایک GitHub Action اسے detect کرے گا، پھر زبان کا label پڑھے گا، اور اس زبان کے تراجم manage کرنے والی GitHub Discussions کو اپڈیٹ کرے گا تاکہ لوگوں کو بتایا جائے کہ review کے لیے نیا ترجمہ ہے۔ |
||||
|
|
||||
|
جب کوئی مقامی بولنے والا آئے، PR کا review کرے، اور اسے منظور کرے، GitHub Action آ کر `awaiting-review` label ہٹائے گا، اور `approved-1` label شامل کرے گا۔ |
||||
|
|
||||
|
اس طرح، ہم نوٹ کر سکتے ہیں جب نئے تراجم تیار ہوں، کیونکہ ان کے پاس `approved-1` label ہوتا ہے۔ |
||||
|
|
||||
|
## ترجمے کی PRs Merge کریں |
||||
|
|
||||
|
تراجم LLMs اور scripts سے خودکار طور پر generate کیے جاتے ہیں۔ |
||||
|
|
||||
|
ایک GitHub Action ہے جو کسی زبان کے تراجم شامل یا اپڈیٹ کرنے کے لیے دستی طور پر چلایا جا سکتا ہے: [`translate.yml`](https://github.com/fastapi/fastapi/actions/workflows/translate.yml)۔ |
||||
|
|
||||
|
ان زبان کے ترجمے کی PRs کے لیے، تصدیق کریں کہ: |
||||
|
|
||||
|
* PR خودکار تھا (@tiangolo کی طرف سے)، کسی اور صارف نے نہیں بنایا۔ |
||||
|
* اس میں `lang-all` اور `lang-{lang code}` labels ہیں۔ |
||||
|
* اگر PR کم از کم ایک مقامی بولنے والے نے منظور کیا ہو، آپ اسے merge کر سکتے ہیں۔ |
||||
|
|
||||
|
## PRs کا Review کریں |
||||
|
|
||||
|
* اگر PR نہیں بتاتی کہ یہ کیا کرتی ہے یا کیوں، اگر ایسا لگے کہ مفید ہو سکتی ہے، مزید معلومات مانگیں۔ ورنہ، آزادانہ طور پر اسے بند کر دیں۔ |
||||
|
|
||||
|
* اگر PR spam لگے، بے معنی لگے، صرف اعداد و شمار تبدیل کرنے کے لیے ("contributor" ظاہر ہونے کے لیے) یا اسی طرح، آپ اسے `invalid` نشان زد کر سکتے ہیں، اور یہ خودکار طور پر بند ہو جائے گی۔ |
||||
|
|
||||
|
* اگر PR AI سے generate شدہ لگتی ہے، اور ایسا لگے کہ اس کا review کرنا prompt لکھنے سے زیادہ وقت لے گا، اسے `maybe-ai` نشان زد کریں، اور یہ خودکار طور پر بند ہو جائے گی۔ |
||||
|
|
||||
|
* PR کا کوئی مخصوص use case ہونا چاہیے جو یہ حل کر رہی ہو۔ |
||||
|
|
||||
|
* اگر PR feature کے لیے ہے تو اس میں docs ہونے چاہئیں۔ |
||||
|
* جب تک یہ ایسی feature نہ ہو جسے ہم حوصلہ شکنی کرنا چاہتے ہیں۔ |
||||
|
* Docs میں source مثالی فائل شامل ہونی چاہیے، براہ راست Markdown میں Python نہیں لکھنا چاہیے۔ |
||||
|
* اگر source مثال فائل(فائلوں) کے مختلف Python ورژنز کے لیے مختلف syntax ہو سکتے ہیں، تو فائل کے مختلف ورژنز ہونے چاہئیں، اور docs میں tabs میں دکھائے جانے چاہئیں۔ |
||||
|
* Source مثال ٹیسٹ کرنے والے tests ہونے چاہئیں۔ |
||||
|
* PR لاگو کرنے سے پہلے، نئے tests fail ہونے چاہئیں۔ |
||||
|
* PR لاگو کرنے کے بعد، نئے tests pass ہونے چاہئیں۔ |
||||
|
* Coverage 100% رہنا چاہیے۔ |
||||
|
* اگر آپ دیکھیں کہ PR درست ہے، یا ہم نے بحث کی اور فیصلہ کیا کہ اسے قبول کیا جائے، آپ PR کے اوپر commits شامل کر سکتے ہیں اسے بہتر بنانے، docs شامل کرنے، tests، فارمیٹ کرنے، refactor کرنے، اضافی فائلیں ہٹانے وغیرہ کے لیے۔ |
||||
|
* PR میں تبصرہ کرنے کے لیے آزاد محسوس کریں مزید معلومات مانگنے، تبدیلیاں تجویز کرنے وغیرہ کے لیے۔ |
||||
|
* جب آپ سمجھیں کہ PR تیار ہے، اسے اندرونی GitHub project میں میرے review کے لیے منتقل کریں۔ |
||||
|
|
||||
|
## FastAPI People PRs |
||||
|
|
||||
|
ہر مہینے، ایک GitHub Action FastAPI People data اپڈیٹ کرتی ہے۔ وہ PRs اس طرح نظر آتی ہیں: [👥 Update FastAPI People](https://github.com/fastapi/fastapi/pull/11669)۔ |
||||
|
|
||||
|
اگر tests pass ہو رہے ہوں، آپ اسے فوراً merge کر سکتے ہیں۔ |
||||
|
|
||||
|
## Dependabot PRs |
||||
|
|
||||
|
Dependabot مختلف چیزوں کے لیے dependencies اپڈیٹ کرنے کی PRs بنائے گا، اور وہ PRs ملتی جلتی نظر آتی ہیں، لیکن کچھ دوسروں سے بہت زیادہ نازک ہوتی ہیں۔ |
||||
|
|
||||
|
* اگر PR براہ راست dependency کے لیے ہو، تو Dependabot بنیادی dependencies میں `pyproject.toml` تبدیل کر رہا ہے، **اسے merge نہ کریں**۔ 😱 مجھے پہلے چیک کرنے دیں۔ |
||||
|
* اگر PR اندرونی dependencies میں سے کسی کو اپڈیٹ کرتی ہے، مثلاً `pyproject.toml` میں `dev` group، یا GitHub Action ورژنز، اگر tests pass ہو رہے ہیں، release notes (PR میں خلاصے میں دکھائی جاتی ہیں) میں کوئی واضح ممکنہ breaking change نظر نہیں آتی، آپ اسے merge کر سکتے ہیں۔ 😎 |
||||
|
|
||||
|
## GitHub Discussions جوابات نشان زد کریں |
||||
|
|
||||
|
جب GitHub Discussions میں کسی سوال کا جواب دیا گیا ہو، "Mark as answer" پر کلک کرکے جواب نشان زد کریں۔ |
||||
|
|
||||
|
آپ discussions کو [`Questions` جو `Unanswered` ہیں](https://github.com/tiangolo/fastapi/discussions/categories/questions?discussions_q=category:Questions+is:open+is:unanswered) سے فلٹر کر سکتے ہیں۔ |
||||
@ -0,0 +1,39 @@ |
|||||
|
# Repository Management |
||||
|
|
||||
|
یہاں FastAPI repository کی انتظامیہ اور دیکھ بھال کی مختصر تفصیل ہے۔ |
||||
|
|
||||
|
## مالک |
||||
|
|
||||
|
میں، [@tiangolo](https://github.com/tiangolo)، FastAPI repository کا بانی اور مالک ہوں۔ 🤓 |
||||
|
|
||||
|
میں عام طور پر ہر PR کو merge کرنے سے پہلے حتمی review دیتا ہوں۔ میں project کے حتمی فیصلے کرتا ہوں، میں [<abbr title="Benevolent Dictator For Life">BDFL</abbr>](https://en.wikipedia.org/wiki/Benevolent_dictator_for_life) ہوں۔ 😅 |
||||
|
|
||||
|
## ٹیم |
||||
|
|
||||
|
لوگوں کی ایک ٹیم ہے جو project کو manage اور برقرار رکھنے میں مدد کرتی ہے۔ 😎 |
||||
|
|
||||
|
ان کی اجازتوں اور [مخصوص ہدایات](./management-tasks.md) کی مختلف سطحیں ہیں۔ |
||||
|
|
||||
|
وہ جو کام انجام دے سکتے ہیں ان میں سے کچھ یہ ہیں: |
||||
|
|
||||
|
* PRs میں labels شامل کرنا۔ |
||||
|
* PR titles ترمیم کرنا۔ |
||||
|
* PRs کے اوپر commits شامل کرنا تاکہ انہیں بہتر بنایا جا سکے۔ |
||||
|
* GitHub Discussions سوالات میں جوابات نشان زد کرنا، وغیرہ۔ |
||||
|
* PRs کی مخصوص اقسام merge کرنا۔ |
||||
|
|
||||
|
آپ موجودہ ٹیم ممبران [FastAPI کے لوگ - ٹیم](./fastapi-people.md#team) میں دیکھ سکتے ہیں۔ |
||||
|
|
||||
|
ٹیم میں شمولیت صرف دعوت نامے سے ہے، اور میں اجازتیں، ہدایات، یا رکنیت اپڈیٹ یا ہٹا سکتا ہوں۔ |
||||
|
|
||||
|
## FastAPI Experts |
||||
|
|
||||
|
وہ لوگ جو GitHub Discussions میں سب سے زیادہ دوسروں کی مدد کرتے ہیں [**FastAPI Experts**](./fastapi-people.md#fastapi-experts) بن سکتے ہیں۔ |
||||
|
|
||||
|
یہ عام طور پر project میں تعاون کا بہترین طریقہ ہے۔ |
||||
|
|
||||
|
## بیرونی تعاون |
||||
|
|
||||
|
بیرونی تعاون کا بہت خیرمقدم ہے اور اس کی قدر کی جاتی ہے، بشمول سوالات کے جوابات دینا، PRs جمع کرنا وغیرہ۔ 🙇♂️ |
||||
|
|
||||
|
[FastAPI کو برقرار رکھنے میں مدد](./help-fastapi.md#help-maintain-fastapi) کرنے کے بہت سے طریقے ہیں۔ |
||||
@ -0,0 +1,5 @@ |
|||||
|
# FastAPI اور دوستوں کا newsletter |
||||
|
|
||||
|
<iframe data-w-type="embedded" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://xr4n4.mjt.lu/wgt/xr4n4/hj5/form?c=40a44fa4" width="100%" style="height: 800px;"></iframe> |
||||
|
|
||||
|
<script type="text/javascript" src="https://app.mailjet.com/pas-nc-embedded-v1.js"></script> |
||||
@ -0,0 +1,28 @@ |
|||||
|
# Full Stack FastAPI Template { #full-stack-fastapi-template } |
||||
|
|
||||
|
Templates عام طور پر ایک مخصوص setup کے ساتھ آتے ہیں، لیکن یہ لچکدار اور حسب ضرورت بنانے کے قابل ہونے کے لیے ڈیزائن کیے گئے ہیں۔ اس سے آپ انہیں اپنے project کی ضروریات کے مطابق تبدیل اور ڈھال سکتے ہیں، جو انہیں ایک بہترین نقطہ آغاز بناتا ہے۔ 🏁 |
||||
|
|
||||
|
آپ شروع کرنے کے لیے یہ template استعمال کر سکتے ہیں، کیونکہ اس میں ابتدائی setup، security، database اور کچھ API endpoints پہلے سے آپ کے لیے بنے ہوئے ہیں۔ |
||||
|
|
||||
|
GitHub Repository: [Full Stack FastAPI Template](https://github.com/tiangolo/full-stack-fastapi-template) |
||||
|
|
||||
|
## Full Stack FastAPI Template - Technology Stack اور Features { #full-stack-fastapi-template-technology-stack-and-features } |
||||
|
|
||||
|
- ⚡ [**FastAPI**](https://fastapi.tiangolo.com) Python backend API کے لیے۔ |
||||
|
- 🧰 [SQLModel](https://sqlmodel.tiangolo.com) Python SQL database interactions (ORM) کے لیے۔ |
||||
|
- 🔍 [Pydantic](https://docs.pydantic.dev)، FastAPI کے ذریعے استعمال شدہ، data validation اور settings management کے لیے۔ |
||||
|
- 💾 [PostgreSQL](https://www.postgresql.org) بطور SQL database۔ |
||||
|
- 🚀 [React](https://react.dev) frontend کے لیے۔ |
||||
|
- 💃 TypeScript، hooks، Vite، اور جدید frontend stack کے دوسرے حصے استعمال کرتے ہوئے۔ |
||||
|
- 🎨 [Tailwind CSS](https://tailwindcss.com) اور [shadcn/ui](https://ui.shadcn.com) frontend components کے لیے۔ |
||||
|
- 🤖 خودکار طور پر generate شدہ frontend client۔ |
||||
|
- 🧪 [Playwright](https://playwright.dev) End-to-End testing کے لیے۔ |
||||
|
- 🦇 Dark mode support۔ |
||||
|
- 🐋 [Docker Compose](https://www.docker.com) development اور production کے لیے۔ |
||||
|
- 🔒 بطور default محفوظ password hashing۔ |
||||
|
- 🔑 JWT (JSON Web Token) authentication۔ |
||||
|
- 📫 Email پر مبنی password recovery۔ |
||||
|
- ✅ [Pytest](https://pytest.org) کے ساتھ Tests۔ |
||||
|
- 📞 [Traefik](https://traefik.io) بطور reverse proxy / load balancer۔ |
||||
|
- 🚢 Docker Compose استعمال کرتے ہوئے deployment ہدایات، بشمول خودکار HTTPS certificates سنبھالنے کے لیے frontend Traefik proxy سیٹ اپ کرنے کا طریقہ۔ |
||||
|
- 🏭 GitHub Actions پر مبنی CI (continuous integration) اور CD (continuous deployment)۔ |
||||
@ -0,0 +1,348 @@ |
|||||
|
# Python Types کا تعارف { #python-types-intro } |
||||
|
|
||||
|
Python میں اختیاری "type hints" (جنہیں "type annotations" بھی کہا جاتا ہے) کی سپورٹ موجود ہے۔ |
||||
|
|
||||
|
یہ **"type hints"** یا annotations ایک خاص syntax ہیں جو کسی variable کی <dfn title="for example: str, int, float, bool">type</dfn> بیان کرنے کی اجازت دیتے ہیں۔ |
||||
|
|
||||
|
اپنے variables کے لیے types بیان کر کے، ایڈیٹرز اور ٹولز آپ کو بہتر سپورٹ فراہم کر سکتے ہیں۔ |
||||
|
|
||||
|
یہ صرف Python type hints کے بارے میں ایک **فوری tutorial / جائزہ** ہے۔ یہ صرف اتنا کم سے کم احاطہ کرتا ہے جتنا **FastAPI** کے ساتھ استعمال کے لیے ضروری ہے... جو دراصل بہت تھوڑا ہے۔ |
||||
|
|
||||
|
**FastAPI** مکمل طور پر ان type hints پر مبنی ہے، یہ اسے بہت سے فوائد اور فائدے دیتے ہیں۔ |
||||
|
|
||||
|
لیکن اگر آپ کبھی بھی **FastAPI** استعمال نہ کریں، تب بھی ان کے بارے میں تھوڑا سیکھنا آپ کے لیے فائدہ مند ہوگا۔ |
||||
|
|
||||
|
/// note | نوٹ |
||||
|
|
||||
|
اگر آپ Python کے ماہر ہیں، اور آپ type hints کے بارے میں پہلے سے سب کچھ جانتے ہیں، تو اگلے باب پر جائیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## مقصد { #motivation } |
||||
|
|
||||
|
آئیے ایک سادہ مثال سے شروع کرتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/python_types/tutorial001_py310.py *} |
||||
|
|
||||
|
اس پروگرام کو چلانے سے یہ نتیجہ آتا ہے: |
||||
|
|
||||
|
``` |
||||
|
John Doe |
||||
|
``` |
||||
|
|
||||
|
function یہ کرتا ہے: |
||||
|
|
||||
|
* ایک `first_name` اور `last_name` لیتا ہے۔ |
||||
|
* ہر ایک کے پہلے حرف کو `title()` کے ساتھ بڑے حرف میں تبدیل کرتا ہے۔ |
||||
|
* درمیان میں خالی جگہ کے ساتھ انہیں <dfn title="Puts them together, as one. With the contents of one after the other.">جوڑتا</dfn> ہے۔ |
||||
|
|
||||
|
{* ../../docs_src/python_types/tutorial001_py310.py hl[2] *} |
||||
|
|
||||
|
### اس میں ترمیم کریں { #edit-it } |
||||
|
|
||||
|
یہ ایک بہت سادہ پروگرام ہے۔ |
||||
|
|
||||
|
لیکن اب تصور کریں کہ آپ اسے شروع سے لکھ رہے تھے۔ |
||||
|
|
||||
|
کسی وقت آپ نے function کی تعریف شروع کی ہوگی، parameters تیار تھے... |
||||
|
|
||||
|
لیکن پھر آپ کو "وہ method کال کرنا ہے جو پہلے حرف کو بڑے حرف میں تبدیل کرتا ہے"۔ |
||||
|
|
||||
|
کیا وہ `upper` تھا؟ `uppercase`؟ `first_uppercase`؟ `capitalize`؟ |
||||
|
|
||||
|
پھر، آپ پرانے پروگرامر کے دوست، ایڈیٹر autocompletion سے مدد لیتے ہیں۔ |
||||
|
|
||||
|
آپ function کا پہلا parameter `first_name` ٹائپ کرتے ہیں، پھر ایک ڈاٹ (`.`) اور پھر `Ctrl+Space` دبا کر completion شروع کرتے ہیں۔ |
||||
|
|
||||
|
لیکن، افسوس، آپ کو کچھ مفید نہیں ملتا: |
||||
|
|
||||
|
<img src="/img/python-types/image01.png"> |
||||
|
|
||||
|
### Types شامل کریں { #add-types } |
||||
|
|
||||
|
آئیے پچھلے ورژن کی ایک لائن تبدیل کرتے ہیں۔ |
||||
|
|
||||
|
ہم بالکل یہ حصہ تبدیل کریں گے، function کے parameters، اس سے: |
||||
|
|
||||
|
```Python |
||||
|
first_name, last_name |
||||
|
``` |
||||
|
|
||||
|
اس میں: |
||||
|
|
||||
|
```Python |
||||
|
first_name: str, last_name: str |
||||
|
``` |
||||
|
|
||||
|
بس اتنا ہی۔ |
||||
|
|
||||
|
یہ ہیں "type hints": |
||||
|
|
||||
|
{* ../../docs_src/python_types/tutorial002_py310.py hl[1] *} |
||||
|
|
||||
|
یہ وہی نہیں ہے جو default values بیان کرنا ہوتا جیسے: |
||||
|
|
||||
|
```Python |
||||
|
first_name="john", last_name="doe" |
||||
|
``` |
||||
|
|
||||
|
یہ ایک الگ چیز ہے۔ |
||||
|
|
||||
|
ہم colons (`:`) استعمال کر رہے ہیں، نہ کہ equals (`=`)۔ |
||||
|
|
||||
|
اور type hints شامل کرنے سے عام طور پر وہ نہیں بدلتا جو ان کے بغیر ہوتا۔ |
||||
|
|
||||
|
لیکن اب، تصور کریں کہ آپ پھر سے وہ function بنا رہے ہیں، لیکن type hints کے ساتھ۔ |
||||
|
|
||||
|
اسی مقام پر، آپ `Ctrl+Space` سے autocomplete شروع کرتے ہیں اور آپ دیکھتے ہیں: |
||||
|
|
||||
|
<img src="/img/python-types/image02.png"> |
||||
|
|
||||
|
اس کے ساتھ، آپ سکرول کر سکتے ہیں، اختیارات دیکھتے ہوئے، جب تک وہ نہ ملے جو "یاد آتا ہے": |
||||
|
|
||||
|
<img src="/img/python-types/image03.png"> |
||||
|
|
||||
|
## مزید مقصد { #more-motivation } |
||||
|
|
||||
|
یہ function دیکھیں، اس میں پہلے سے type hints ہیں: |
||||
|
|
||||
|
{* ../../docs_src/python_types/tutorial003_py310.py hl[1] *} |
||||
|
|
||||
|
کیونکہ ایڈیٹر variables کی types جانتا ہے، آپ کو صرف completion ہی نہیں ملتی، بلکہ error checks بھی ملتی ہیں: |
||||
|
|
||||
|
<img src="/img/python-types/image04.png"> |
||||
|
|
||||
|
اب آپ جانتے ہیں کہ آپ کو اسے ٹھیک کرنا ہے، `age` کو `str(age)` سے string میں تبدیل کرنا ہے: |
||||
|
|
||||
|
{* ../../docs_src/python_types/tutorial004_py310.py hl[2] *} |
||||
|
|
||||
|
## Types بیان کرنا { #declaring-types } |
||||
|
|
||||
|
آپ نے ابھی type hints بیان کرنے کی اصل جگہ دیکھی۔ Function parameters کے طور پر۔ |
||||
|
|
||||
|
یہ وہ اصل جگہ بھی ہے جہاں آپ انہیں **FastAPI** کے ساتھ استعمال کریں گے۔ |
||||
|
|
||||
|
### سادہ types { #simple-types } |
||||
|
|
||||
|
آپ تمام معیاری Python types بیان کر سکتے ہیں، نہ صرف `str`۔ |
||||
|
|
||||
|
آپ استعمال کر سکتے ہیں، مثال کے طور پر: |
||||
|
|
||||
|
* `int` |
||||
|
* `float` |
||||
|
* `bool` |
||||
|
* `bytes` |
||||
|
|
||||
|
{* ../../docs_src/python_types/tutorial005_py310.py hl[1] *} |
||||
|
|
||||
|
### `typing` module { #typing-module } |
||||
|
|
||||
|
کچھ اضافی استعمال کے معاملات کے لیے، آپ کو معیاری لائبریری `typing` module سے کچھ چیزیں import کرنی پڑ سکتی ہیں، مثال کے طور پر جب آپ بیان کرنا چاہیں کہ کسی چیز کی "کوئی بھی type" ہے، تو آپ `typing` سے `Any` استعمال کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from typing import Any |
||||
|
|
||||
|
|
||||
|
def some_function(data: Any): |
||||
|
print(data) |
||||
|
``` |
||||
|
|
||||
|
### Generic types { #generic-types } |
||||
|
|
||||
|
کچھ types اپنے اندرونی types بیان کرنے کے لیے مربع بریکٹس میں "type parameters" لے سکتی ہیں، مثال کے طور پر "strings کی list" کو `list[str]` لکھا جائے گا۔ |
||||
|
|
||||
|
وہ types جو type parameters لے سکتی ہیں، انہیں **Generic types** یا **Generics** کہا جاتا ہے۔ |
||||
|
|
||||
|
آپ وہی بلٹ ان types بطور generics استعمال کر سکتے ہیں (مربع بریکٹس اور اندر types کے ساتھ): |
||||
|
|
||||
|
* `list` |
||||
|
* `tuple` |
||||
|
* `set` |
||||
|
* `dict` |
||||
|
|
||||
|
#### List { #list } |
||||
|
|
||||
|
مثال کے طور پر، آئیے ایک variable کو `str` کی `list` کے طور پر بیان کرتے ہیں۔ |
||||
|
|
||||
|
اسی colon (`:`) syntax کے ساتھ variable بیان کریں۔ |
||||
|
|
||||
|
Type کے طور پر `list` رکھیں۔ |
||||
|
|
||||
|
چونکہ list ایک ایسی type ہے جس میں کچھ اندرونی types ہیں، آپ انہیں مربع بریکٹس میں رکھتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/python_types/tutorial006_py310.py hl[1] *} |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
مربع بریکٹس میں وہ اندرونی types "type parameters" کہلاتی ہیں۔ |
||||
|
|
||||
|
اس صورت میں، `str` وہ type parameter ہے جو `list` کو دیا گیا ہے۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
اس کا مطلب ہے: "variable `items` ایک `list` ہے، اور اس list کا ہر آئٹم ایک `str` ہے"۔ |
||||
|
|
||||
|
ایسا کرنے سے، آپ کا ایڈیٹر list سے آئٹمز پر عمل کرتے ہوئے بھی سپورٹ فراہم کر سکتا ہے: |
||||
|
|
||||
|
<img src="/img/python-types/image05.png"> |
||||
|
|
||||
|
Types کے بغیر، یہ تقریباً ناممکن ہے۔ |
||||
|
|
||||
|
غور کریں کہ variable `item` list `items` کے عناصر میں سے ایک ہے۔ |
||||
|
|
||||
|
اور پھر بھی، ایڈیٹر جانتا ہے کہ یہ ایک `str` ہے، اور اس کے لیے سپورٹ فراہم کرتا ہے۔ |
||||
|
|
||||
|
#### Tuple اور Set { #tuple-and-set } |
||||
|
|
||||
|
`tuple` اور `set` بیان کرنے کے لیے بھی آپ ایسا ہی کریں گے: |
||||
|
|
||||
|
{* ../../docs_src/python_types/tutorial007_py310.py hl[1] *} |
||||
|
|
||||
|
اس کا مطلب ہے: |
||||
|
|
||||
|
* Variable `items_t` ایک `tuple` ہے جس میں 3 آئٹمز ہیں، ایک `int`، ایک اور `int`، اور ایک `str`۔ |
||||
|
* Variable `items_s` ایک `set` ہے، اور اس کا ہر آئٹم `bytes` type کا ہے۔ |
||||
|
|
||||
|
#### Dict { #dict } |
||||
|
|
||||
|
`dict` بیان کرنے کے لیے، آپ کوما سے الگ کر کے 2 type parameters دیتے ہیں۔ |
||||
|
|
||||
|
پہلا type parameter `dict` کی keys کے لیے ہے۔ |
||||
|
|
||||
|
دوسرا type parameter `dict` کی values کے لیے ہے: |
||||
|
|
||||
|
{* ../../docs_src/python_types/tutorial008_py310.py hl[1] *} |
||||
|
|
||||
|
اس کا مطلب ہے: |
||||
|
|
||||
|
* Variable `prices` ایک `dict` ہے: |
||||
|
* اس `dict` کی keys `str` type کی ہیں (فرض کریں، ہر آئٹم کا نام)۔ |
||||
|
* اس `dict` کی values `float` type کی ہیں (فرض کریں، ہر آئٹم کی قیمت)۔ |
||||
|
|
||||
|
#### Union { #union } |
||||
|
|
||||
|
آپ بیان کر سکتے ہیں کہ ایک variable **کئی types** میں سے کوئی بھی ہو سکتا ہے، مثال کے طور پر، ایک `int` یا ایک `str`۔ |
||||
|
|
||||
|
اسے بیان کرنے کے لیے آپ دونوں types کو الگ کرنے کے لیے <dfn title='also called "bitwise or operator", but that meaning is not relevant here'>عمودی بار (`|`)</dfn> استعمال کرتے ہیں۔ |
||||
|
|
||||
|
اسے "union" کہا جاتا ہے، کیونکہ variable ان دو types کے مجموعے میں سے کچھ بھی ہو سکتا ہے۔ |
||||
|
|
||||
|
```Python hl_lines="1" |
||||
|
{!> ../../docs_src/python_types/tutorial008b_py310.py!} |
||||
|
``` |
||||
|
|
||||
|
اس کا مطلب ہے کہ `item` ایک `int` یا ایک `str` ہو سکتا ہے۔ |
||||
|
|
||||
|
#### ممکنہ طور پر `None` { #possibly-none } |
||||
|
|
||||
|
آپ بیان کر سکتے ہیں کہ کسی value کی type ہو سکتی ہے، جیسے `str`، لیکن یہ `None` بھی ہو سکتی ہے۔ |
||||
|
|
||||
|
//// tab | Python 3.10+ |
||||
|
|
||||
|
```Python hl_lines="1" |
||||
|
{!> ../../docs_src/python_types/tutorial009_py310.py!} |
||||
|
``` |
||||
|
|
||||
|
//// |
||||
|
|
||||
|
صرف `str` کے بجائے `str | None` استعمال کرنے سے ایڈیٹر آپ کو ان غلطیوں کا پتہ لگانے میں مدد کر سکے گا جہاں آپ فرض کر رہے ہوں کہ کوئی value ہمیشہ `str` ہے، جبکہ یہ دراصل `None` بھی ہو سکتی ہے۔ |
||||
|
|
||||
|
### بطور types Classes { #classes-as-types } |
||||
|
|
||||
|
آپ کسی class کو بھی variable کی type کے طور پر بیان کر سکتے ہیں۔ |
||||
|
|
||||
|
فرض کریں آپ کے پاس ایک `Person` class ہے، جس میں ایک name ہے: |
||||
|
|
||||
|
{* ../../docs_src/python_types/tutorial010_py310.py hl[1:3] *} |
||||
|
|
||||
|
پھر آپ ایک variable کو `Person` type کا بیان کر سکتے ہیں: |
||||
|
|
||||
|
{* ../../docs_src/python_types/tutorial010_py310.py hl[6] *} |
||||
|
|
||||
|
اور پھر، آپ کو دوبارہ تمام ایڈیٹر سپورٹ ملتی ہے: |
||||
|
|
||||
|
<img src="/img/python-types/image06.png"> |
||||
|
|
||||
|
غور کریں کہ اس کا مطلب ہے "`one_person` class `Person` کی ایک **instance** ہے"۔ |
||||
|
|
||||
|
اس کا مطلب یہ نہیں کہ "`one_person` وہ **class** ہے جو `Person` کہلاتی ہے"۔ |
||||
|
|
||||
|
## Pydantic models { #pydantic-models } |
||||
|
|
||||
|
[Pydantic](https://docs.pydantic.dev/) data validation کے لیے ایک Python لائبریری ہے۔ |
||||
|
|
||||
|
آپ ڈیٹا کی "شکل" attributes والی classes کے طور پر بیان کرتے ہیں۔ |
||||
|
|
||||
|
اور ہر attribute کی ایک type ہوتی ہے۔ |
||||
|
|
||||
|
پھر آپ کچھ values کے ساتھ اس class کی ایک instance بناتے ہیں اور یہ values کی توثیق کرے گا، انہیں مناسب type میں تبدیل کرے گا (اگر ایسا ہو) اور آپ کو تمام ڈیٹا کے ساتھ ایک object دے گا۔ |
||||
|
|
||||
|
اور آپ کو اس نتیجے میں ملنے والی object کے ساتھ تمام ایڈیٹر سپورٹ ملتی ہے۔ |
||||
|
|
||||
|
سرکاری Pydantic دستاویزات سے ایک مثال: |
||||
|
|
||||
|
{* ../../docs_src/python_types/tutorial011_py310.py *} |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
[Pydantic کے بارے میں مزید جاننے کے لیے، اس کی دستاویزات دیکھیں](https://docs.pydantic.dev/)۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
**FastAPI** مکمل طور پر Pydantic پر مبنی ہے۔ |
||||
|
|
||||
|
آپ [Tutorial - User Guide](tutorial/index.md) میں عملی طور پر یہ سب بہت زیادہ دیکھیں گے۔ |
||||
|
|
||||
|
## Metadata Annotations کے ساتھ Type Hints { #type-hints-with-metadata-annotations } |
||||
|
|
||||
|
Python میں ایک خصوصیت بھی ہے جو `Annotated` استعمال کر کے ان type hints میں **اضافی <dfn title="Data about the data, in this case, information about the type, e.g. a description.">metadata</dfn>** رکھنے کی اجازت دیتی ہے۔ |
||||
|
|
||||
|
آپ `typing` سے `Annotated` import کر سکتے ہیں۔ |
||||
|
|
||||
|
{* ../../docs_src/python_types/tutorial013_py310.py hl[1,4] *} |
||||
|
|
||||
|
Python خود اس `Annotated` کے ساتھ کچھ نہیں کرتا۔ اور ایڈیٹرز اور دیگر ٹولز کے لیے، type ابھی بھی `str` ہے۔ |
||||
|
|
||||
|
لیکن آپ `Annotated` میں اس جگہ کو **FastAPI** کو اضافی metadata فراہم کرنے کے لیے استعمال کر سکتے ہیں کہ آپ اپنی ایپلیکیشن کو کیسے چلانا چاہتے ہیں۔ |
||||
|
|
||||
|
یاد رکھنے کی اہم بات یہ ہے کہ `Annotated` کو دیا جانے والا **پہلا *type parameter*** ہی **اصل type** ہے۔ باقی سب دوسرے ٹولز کے لیے صرف metadata ہے۔ |
||||
|
|
||||
|
ابھی کے لیے، آپ کو بس یہ جاننا ہے کہ `Annotated` موجود ہے، اور یہ معیاری Python ہے۔ 😎 |
||||
|
|
||||
|
بعد میں آپ دیکھیں گے کہ یہ کتنا **طاقتور** ہو سکتا ہے۔ |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
یہ حقیقت کہ یہ **معیاری Python** ہے اس کا مطلب ہے کہ آپ کو اپنے ایڈیٹر میں ابھی بھی **بہترین ممکنہ ڈویلپر تجربہ** ملے گا، ان ٹولز کے ساتھ جو آپ code کا تجزیہ اور refactor کرنے کے لیے استعمال کرتے ہیں، وغیرہ۔ ✨ |
||||
|
|
||||
|
اور یہ بھی کہ آپ کا code بہت سے دیگر Python ٹولز اور لائبریریز کے ساتھ بہت ہم آہنگ ہوگا۔ 🚀 |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
## **FastAPI** میں Type hints { #type-hints-in-fastapi } |
||||
|
|
||||
|
**FastAPI** ان type hints کا فائدہ اٹھاتا ہے کئی کام کرنے کے لیے۔ |
||||
|
|
||||
|
**FastAPI** کے ساتھ آپ type hints کے ساتھ parameters بیان کرتے ہیں اور آپ کو ملتا ہے: |
||||
|
|
||||
|
* **ایڈیٹر سپورٹ**۔ |
||||
|
* **Type checks**۔ |
||||
|
|
||||
|
...اور **FastAPI** انہی اعلانات کو استعمال کرتا ہے: |
||||
|
|
||||
|
* **ضروریات بیان کرنے** کے لیے: request path parameters، query parameters، headers، bodies، dependencies وغیرہ سے۔ |
||||
|
* **ڈیٹا تبدیل کرنے** کے لیے: request سے مطلوبہ type میں۔ |
||||
|
* **ڈیٹا کی توثیق** کے لیے: ہر request سے آنے والے: |
||||
|
* ڈیٹا غلط ہونے پر client کو واپس بھیجی جانے والی **خودکار غلطیاں** بنانا۔ |
||||
|
* OpenAPI استعمال کرتے ہوئے API کی **دستاویزات** بنانا: |
||||
|
* جو پھر خودکار تعاملی دستاویزات کے یوزر انٹرفیسز استعمال کرتی ہیں۔ |
||||
|
|
||||
|
یہ سب خلاصہ لگ سکتا ہے۔ فکر نہ کریں۔ آپ [Tutorial - User Guide](tutorial/index.md) میں یہ سب عمل میں دیکھیں گے۔ |
||||
|
|
||||
|
اہم بات یہ ہے کہ معیاری Python types استعمال کر کے، ایک ہی جگہ پر (مزید classes، decorators وغیرہ شامل کرنے کے بجائے)، **FastAPI** آپ کا بہت سا کام خود کر لے گا۔ |
||||
|
|
||||
|
/// info | معلومات |
||||
|
|
||||
|
اگر آپ پورا tutorial پڑھ چکے ہیں اور types کے بارے میں مزید جاننے واپس آئے ہیں، تو ایک اچھا ذریعہ [`mypy` کی "cheat sheet"](https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html) ہے۔ |
||||
|
|
||||
|
/// |
||||
@ -0,0 +1,24 @@ |
|||||
|
# `APIRouter` class |
||||
|
|
||||
|
یہاں `APIRouter` class کی حوالہ جاتی معلومات ہیں، اس کے تمام parameters، attributes اور methods کے ساتھ۔ |
||||
|
|
||||
|
آپ `APIRouter` class کو براہ راست `fastapi` سے import کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi import APIRouter |
||||
|
``` |
||||
|
|
||||
|
::: fastapi.APIRouter |
||||
|
options: |
||||
|
members: |
||||
|
- websocket |
||||
|
- include_router |
||||
|
- get |
||||
|
- put |
||||
|
- post |
||||
|
- delete |
||||
|
- options |
||||
|
- head |
||||
|
- patch |
||||
|
- trace |
||||
|
- on_event |
||||
@ -0,0 +1,11 @@ |
|||||
|
# Background Tasks - `BackgroundTasks` |
||||
|
|
||||
|
آپ *path operation function* یا dependency function میں `BackgroundTasks` type کا parameter declare کر سکتے ہیں، اور پھر اسے response بھیجنے کے بعد background tasks کے عمل کو schedule کرنے کے لیے استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
آپ اسے براہ راست `fastapi` سے import کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi import BackgroundTasks |
||||
|
``` |
||||
|
|
||||
|
::: fastapi.BackgroundTasks |
||||
@ -0,0 +1,29 @@ |
|||||
|
# Dependencies - `Depends()` اور `Security()` |
||||
|
|
||||
|
## `Depends()` |
||||
|
|
||||
|
Dependencies کو بنیادی طور پر خاص function `Depends()` کے ذریعے سنبھالا جاتا ہے جو ایک callable لیتا ہے۔ |
||||
|
|
||||
|
یہاں اس کی اور اس کے parameters کی حوالہ جاتی معلومات ہیں۔ |
||||
|
|
||||
|
آپ اسے براہ راست `fastapi` سے import کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi import Depends |
||||
|
``` |
||||
|
|
||||
|
::: fastapi.Depends |
||||
|
|
||||
|
## `Security()` |
||||
|
|
||||
|
بہت سے منظرناموں میں، آپ `Depends()` استعمال کر کے dependencies کے ذریعے security (authorization، authentication، وغیرہ) کو سنبھال سکتے ہیں۔ |
||||
|
|
||||
|
لیکن جب آپ OAuth2 scopes بھی declare کرنا چاہیں، تو آپ `Depends()` کی بجائے `Security()` استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
آپ `Security()` کو براہ راست `fastapi` سے import کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi import Security |
||||
|
``` |
||||
|
|
||||
|
::: fastapi.Security |
||||
@ -0,0 +1,3 @@ |
|||||
|
# Encoders - `jsonable_encoder` |
||||
|
|
||||
|
::: fastapi.encoders.jsonable_encoder |
||||
@ -0,0 +1,20 @@ |
|||||
|
# Exceptions - `HTTPException` اور `WebSocketException` |
||||
|
|
||||
|
یہ وہ exceptions ہیں جو آپ client کو غلطیاں دکھانے کے لیے raise کر سکتے ہیں۔ |
||||
|
|
||||
|
جب آپ کوئی exception raise کرتے ہیں، جیسا کہ عام Python میں ہوتا ہے، باقی کا عمل روک دیا جاتا ہے۔ اس طرح آپ code میں کہیں سے بھی یہ exceptions raise کر کے request کو روک سکتے ہیں اور client کو غلطی دکھا سکتے ہیں۔ |
||||
|
|
||||
|
آپ یہ استعمال کر سکتے ہیں: |
||||
|
|
||||
|
* `HTTPException` |
||||
|
* `WebSocketException` |
||||
|
|
||||
|
یہ exceptions براہ راست `fastapi` سے import کی جا سکتی ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi import HTTPException, WebSocketException |
||||
|
``` |
||||
|
|
||||
|
::: fastapi.HTTPException |
||||
|
|
||||
|
::: fastapi.WebSocketException |
||||
@ -0,0 +1,31 @@ |
|||||
|
# `FastAPI` class |
||||
|
|
||||
|
یہاں `FastAPI` class کی حوالہ جاتی معلومات ہیں، اس کے تمام parameters، attributes اور methods کے ساتھ۔ |
||||
|
|
||||
|
آپ `FastAPI` class کو براہ راست `fastapi` سے import کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi import FastAPI |
||||
|
``` |
||||
|
|
||||
|
::: fastapi.FastAPI |
||||
|
options: |
||||
|
members: |
||||
|
- openapi_version |
||||
|
- webhooks |
||||
|
- state |
||||
|
- dependency_overrides |
||||
|
- openapi |
||||
|
- websocket |
||||
|
- include_router |
||||
|
- get |
||||
|
- put |
||||
|
- post |
||||
|
- delete |
||||
|
- options |
||||
|
- head |
||||
|
- patch |
||||
|
- trace |
||||
|
- on_event |
||||
|
- middleware |
||||
|
- exception_handler |
||||
@ -0,0 +1,11 @@ |
|||||
|
# `HTTPConnection` class |
||||
|
|
||||
|
جب آپ ایسی dependencies define کرنا چاہیں جو HTTP اور WebSockets دونوں کے ساتھ مطابقت رکھتی ہوں، تو آپ `Request` یا `WebSocket` کی بجائے `HTTPConnection` لینے والا parameter define کر سکتے ہیں۔ |
||||
|
|
||||
|
آپ اسے `fastapi.requests` سے import کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi.requests import HTTPConnection |
||||
|
``` |
||||
|
|
||||
|
::: fastapi.requests.HTTPConnection |
||||
@ -0,0 +1,6 @@ |
|||||
|
# حوالہ جات |
||||
|
|
||||
|
یہاں حوالہ جات یا code API موجود ہے، جس میں classes، functions، parameters، attributes، اور FastAPI کے تمام وہ حصے شامل ہیں جو آپ اپنی applications میں استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
اگر آپ **FastAPI سیکھنا** چاہتے ہیں تو آپ کے لیے |
||||
|
[FastAPI ٹیوٹوریل](https://fastapi.tiangolo.com/tutorial/) پڑھنا زیادہ بہتر ہوگا۔ |
||||
@ -0,0 +1,37 @@ |
|||||
|
# Middleware |
||||
|
|
||||
|
Starlette کی طرف سے براہ راست فراہم کردہ کئی middlewares دستیاب ہیں۔ |
||||
|
|
||||
|
ان کے بارے میں مزید پڑھیں [FastAPI دستاویزات میں Middleware](https://fastapi.tiangolo.com/advanced/middleware/)۔ |
||||
|
|
||||
|
::: fastapi.middleware.cors.CORSMiddleware |
||||
|
|
||||
|
اسے `fastapi` سے import کیا جا سکتا ہے: |
||||
|
|
||||
|
```python |
||||
|
from fastapi.middleware.cors import CORSMiddleware |
||||
|
``` |
||||
|
|
||||
|
::: fastapi.middleware.gzip.GZipMiddleware |
||||
|
|
||||
|
اسے `fastapi` سے import کیا جا سکتا ہے: |
||||
|
|
||||
|
```python |
||||
|
from fastapi.middleware.gzip import GZipMiddleware |
||||
|
``` |
||||
|
|
||||
|
::: fastapi.middleware.httpsredirect.HTTPSRedirectMiddleware |
||||
|
|
||||
|
اسے `fastapi` سے import کیا جا سکتا ہے: |
||||
|
|
||||
|
```python |
||||
|
from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware |
||||
|
``` |
||||
|
|
||||
|
::: fastapi.middleware.trustedhost.TrustedHostMiddleware |
||||
|
|
||||
|
اسے `fastapi` سے import کیا جا سکتا ہے: |
||||
|
|
||||
|
```python |
||||
|
from fastapi.middleware.trustedhost import TrustedHostMiddleware |
||||
|
``` |
||||
@ -0,0 +1,11 @@ |
|||||
|
# OpenAPI `docs` |
||||
|
|
||||
|
OpenAPI خودکار UI دستاویزات کو سنبھالنے کے لیے utilities، بشمول Swagger UI (بطور ڈیفالٹ `/docs` پر) اور ReDoc (بطور ڈیفالٹ `/redoc` پر)۔ |
||||
|
|
||||
|
::: fastapi.openapi.docs.get_swagger_ui_html |
||||
|
|
||||
|
::: fastapi.openapi.docs.get_redoc_html |
||||
|
|
||||
|
::: fastapi.openapi.docs.get_swagger_ui_oauth2_redirect_html |
||||
|
|
||||
|
::: fastapi.openapi.docs.swagger_ui_default_parameters |
||||
@ -0,0 +1,5 @@ |
|||||
|
# OpenAPI |
||||
|
|
||||
|
OpenAPI کو سنبھالنے کے لیے کئی utilities دستیاب ہیں۔ |
||||
|
|
||||
|
عام طور پر آپ کو انہیں استعمال کرنے کی ضرورت نہیں ہوتی جب تک کہ آپ کے پاس کوئی مخصوص جدید استعمال کا معاملہ نہ ہو جس کے لیے ان کی ضرورت ہو۔ |
||||
@ -0,0 +1,5 @@ |
|||||
|
# OpenAPI `models` |
||||
|
|
||||
|
OpenAPI Pydantic models جو تیار کردہ OpenAPI کو generate اور validate کرنے کے لیے استعمال ہوتے ہیں۔ |
||||
|
|
||||
|
::: fastapi.openapi.models |
||||
@ -0,0 +1,35 @@ |
|||||
|
# Request Parameters |
||||
|
|
||||
|
یہاں request parameters کی حوالہ جاتی معلومات ہیں۔ |
||||
|
|
||||
|
یہ وہ خاص functions ہیں جو آپ *path operation function* کے parameters یا dependency functions میں `Annotated` کے ساتھ استعمال کر کے request سے ڈیٹا حاصل کر سکتے ہیں۔ |
||||
|
|
||||
|
اس میں شامل ہیں: |
||||
|
|
||||
|
* `Query()` |
||||
|
* `Path()` |
||||
|
* `Body()` |
||||
|
* `Cookie()` |
||||
|
* `Header()` |
||||
|
* `Form()` |
||||
|
* `File()` |
||||
|
|
||||
|
آپ ان سب کو براہ راست `fastapi` سے import کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi import Body, Cookie, File, Form, Header, Path, Query |
||||
|
``` |
||||
|
|
||||
|
::: fastapi.Query |
||||
|
|
||||
|
::: fastapi.Path |
||||
|
|
||||
|
::: fastapi.Body |
||||
|
|
||||
|
::: fastapi.Cookie |
||||
|
|
||||
|
::: fastapi.Header |
||||
|
|
||||
|
::: fastapi.Form |
||||
|
|
||||
|
::: fastapi.File |
||||
@ -0,0 +1,19 @@ |
|||||
|
# `Request` class |
||||
|
|
||||
|
آپ *path operation function* یا dependency میں `Request` type کا parameter declare کر سکتے ہیں اور پھر بغیر کسی validation وغیرہ کے خام request object تک براہ راست رسائی حاصل کر سکتے ہیں۔ |
||||
|
|
||||
|
اس کے بارے میں مزید پڑھیں [FastAPI دستاویزات میں Request کو براہ راست استعمال کرنا](https://fastapi.tiangolo.com/advanced/using-request-directly/) |
||||
|
|
||||
|
آپ اسے براہ راست `fastapi` سے import کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi import Request |
||||
|
``` |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
جب آپ ایسی dependencies define کرنا چاہیں جو HTTP اور WebSockets دونوں کے ساتھ مطابقت رکھتی ہوں، تو آپ `Request` یا `WebSocket` کی بجائے `HTTPConnection` لینے والا parameter define کر سکتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
::: fastapi.Request |
||||
@ -0,0 +1,15 @@ |
|||||
|
# `Response` class |
||||
|
|
||||
|
آپ *path operation function* یا dependency میں `Response` type کا parameter declare کر سکتے ہیں اور پھر response کے لیے ڈیٹا جیسے headers یا cookies سیٹ کر سکتے ہیں۔ |
||||
|
|
||||
|
آپ اسے براہ راست ایک instance بنانے اور اپنی *path operations* سے واپس کرنے کے لیے بھی استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
اس کے بارے میں مزید پڑھیں [FastAPI دستاویزات میں حسب ضرورت Response واپس کرنا](https://fastapi.tiangolo.com/advanced/response-directly/#returning-a-custom-response) |
||||
|
|
||||
|
آپ اسے براہ راست `fastapi` سے import کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi import Response |
||||
|
``` |
||||
|
|
||||
|
::: fastapi.Response |
||||
@ -0,0 +1,172 @@ |
|||||
|
# حسب ضرورت Response Classes - File، HTML، Redirect، Streaming، وغیرہ |
||||
|
|
||||
|
کئی حسب ضرورت response classes دستیاب ہیں جنہیں آپ ایک instance بنا کر اپنی *path operations* سے براہ راست واپس کر سکتے ہیں۔ |
||||
|
|
||||
|
اس کے بارے میں مزید پڑھیں [FastAPI دستاویزات میں حسب ضرورت Response - HTML، Stream، File، اور دیگر](https://fastapi.tiangolo.com/advanced/custom-response/)۔ |
||||
|
|
||||
|
آپ انہیں براہ راست `fastapi.responses` سے import کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi.responses import ( |
||||
|
FileResponse, |
||||
|
HTMLResponse, |
||||
|
JSONResponse, |
||||
|
ORJSONResponse, |
||||
|
PlainTextResponse, |
||||
|
RedirectResponse, |
||||
|
Response, |
||||
|
StreamingResponse, |
||||
|
UJSONResponse, |
||||
|
) |
||||
|
``` |
||||
|
|
||||
|
## FastAPI Responses |
||||
|
|
||||
|
کچھ حسب ضرورت FastAPI response classes تھیں جو JSON کی کارکردگی کو بہتر بنانے کے لیے بنائی گئی تھیں۔ |
||||
|
|
||||
|
تاہم، اب یہ deprecated ہو چکی ہیں کیونکہ اب آپ [Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/) استعمال کر کے بہتر کارکردگی حاصل کر سکتے ہیں۔ |
||||
|
|
||||
|
اس طرح، Pydantic ڈیٹا کو Rust کی طرف JSON bytes میں serialize کرے گا، جو ان حسب ضرورت JSON responses سے بہتر کارکردگی فراہم کرے گا۔ |
||||
|
|
||||
|
اس کے بارے میں مزید پڑھیں [حسب ضرورت Response - HTML، Stream، File، اور دیگر - `orjson` یا Response Model](https://fastapi.tiangolo.com/advanced/custom-response/#orjson-or-response-model)۔ |
||||
|
|
||||
|
::: fastapi.responses.UJSONResponse |
||||
|
options: |
||||
|
members: |
||||
|
- charset |
||||
|
- status_code |
||||
|
- media_type |
||||
|
- body |
||||
|
- background |
||||
|
- raw_headers |
||||
|
- render |
||||
|
- init_headers |
||||
|
- headers |
||||
|
- set_cookie |
||||
|
- delete_cookie |
||||
|
|
||||
|
::: fastapi.responses.ORJSONResponse |
||||
|
options: |
||||
|
members: |
||||
|
- charset |
||||
|
- status_code |
||||
|
- media_type |
||||
|
- body |
||||
|
- background |
||||
|
- raw_headers |
||||
|
- render |
||||
|
- init_headers |
||||
|
- headers |
||||
|
- set_cookie |
||||
|
- delete_cookie |
||||
|
|
||||
|
## Starlette Responses |
||||
|
|
||||
|
آپ ان سب کے بارے میں مزید پڑھ سکتے ہیں [FastAPI دستاویزات میں حسب ضرورت Response](https://fastapi.tiangolo.com/advanced/custom-response/) اور [Starlette دستاویزات میں Responses](https://starlette.dev/responses/)۔ |
||||
|
|
||||
|
::: fastapi.responses.FileResponse |
||||
|
options: |
||||
|
members: |
||||
|
- chunk_size |
||||
|
- charset |
||||
|
- status_code |
||||
|
- media_type |
||||
|
- body |
||||
|
- background |
||||
|
- raw_headers |
||||
|
- render |
||||
|
- init_headers |
||||
|
- headers |
||||
|
- set_cookie |
||||
|
- delete_cookie |
||||
|
|
||||
|
::: fastapi.responses.HTMLResponse |
||||
|
options: |
||||
|
members: |
||||
|
- charset |
||||
|
- status_code |
||||
|
- media_type |
||||
|
- body |
||||
|
- background |
||||
|
- raw_headers |
||||
|
- render |
||||
|
- init_headers |
||||
|
- headers |
||||
|
- set_cookie |
||||
|
- delete_cookie |
||||
|
|
||||
|
::: fastapi.responses.JSONResponse |
||||
|
options: |
||||
|
members: |
||||
|
- charset |
||||
|
- status_code |
||||
|
- media_type |
||||
|
- body |
||||
|
- background |
||||
|
- raw_headers |
||||
|
- render |
||||
|
- init_headers |
||||
|
- headers |
||||
|
- set_cookie |
||||
|
- delete_cookie |
||||
|
|
||||
|
::: fastapi.responses.PlainTextResponse |
||||
|
options: |
||||
|
members: |
||||
|
- charset |
||||
|
- status_code |
||||
|
- media_type |
||||
|
- body |
||||
|
- background |
||||
|
- raw_headers |
||||
|
- render |
||||
|
- init_headers |
||||
|
- headers |
||||
|
- set_cookie |
||||
|
- delete_cookie |
||||
|
|
||||
|
::: fastapi.responses.RedirectResponse |
||||
|
options: |
||||
|
members: |
||||
|
- charset |
||||
|
- status_code |
||||
|
- media_type |
||||
|
- body |
||||
|
- background |
||||
|
- raw_headers |
||||
|
- render |
||||
|
- init_headers |
||||
|
- headers |
||||
|
- set_cookie |
||||
|
- delete_cookie |
||||
|
|
||||
|
::: fastapi.responses.Response |
||||
|
options: |
||||
|
members: |
||||
|
- charset |
||||
|
- status_code |
||||
|
- media_type |
||||
|
- body |
||||
|
- background |
||||
|
- raw_headers |
||||
|
- render |
||||
|
- init_headers |
||||
|
- headers |
||||
|
- set_cookie |
||||
|
- delete_cookie |
||||
|
|
||||
|
::: fastapi.responses.StreamingResponse |
||||
|
options: |
||||
|
members: |
||||
|
- body_iterator |
||||
|
- charset |
||||
|
- status_code |
||||
|
- media_type |
||||
|
- body |
||||
|
- background |
||||
|
- raw_headers |
||||
|
- render |
||||
|
- init_headers |
||||
|
- headers |
||||
|
- set_cookie |
||||
|
- delete_cookie |
||||
@ -0,0 +1,75 @@ |
|||||
|
# Security ٹولز |
||||
|
|
||||
|
جب آپ کو OAuth2 scopes کے ساتھ dependencies declare کرنی ہوں تو آپ `Security()` استعمال کرتے ہیں۔ |
||||
|
|
||||
|
لیکن آپ کو پھر بھی یہ define کرنا ہوگا کہ dependable کیا ہے، یعنی وہ callable جو آپ `Depends()` یا `Security()` کو parameter کے طور پر دیتے ہیں۔ |
||||
|
|
||||
|
ایسے dependables بنانے کے لیے کئی ٹولز دستیاب ہیں، اور یہ OpenAPI میں ضم ہو جاتے ہیں تاکہ یہ خودکار docs UI میں دکھائے جائیں، خودکار طور پر بنائے گئے clients اور SDKs کے ذریعے استعمال ہو سکیں، وغیرہ۔ |
||||
|
|
||||
|
آپ انہیں `fastapi.security` سے import کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi.security import ( |
||||
|
APIKeyCookie, |
||||
|
APIKeyHeader, |
||||
|
APIKeyQuery, |
||||
|
HTTPAuthorizationCredentials, |
||||
|
HTTPBasic, |
||||
|
HTTPBasicCredentials, |
||||
|
HTTPBearer, |
||||
|
HTTPDigest, |
||||
|
OAuth2, |
||||
|
OAuth2AuthorizationCodeBearer, |
||||
|
OAuth2PasswordBearer, |
||||
|
OAuth2PasswordRequestForm, |
||||
|
OAuth2PasswordRequestFormStrict, |
||||
|
OpenIdConnect, |
||||
|
SecurityScopes, |
||||
|
) |
||||
|
``` |
||||
|
|
||||
|
ان کے بارے میں مزید پڑھیں [FastAPI دستاویزات میں Security](https://fastapi.tiangolo.com/tutorial/security/)۔ |
||||
|
|
||||
|
## API Key Security Schemes |
||||
|
|
||||
|
::: fastapi.security.APIKeyCookie |
||||
|
|
||||
|
::: fastapi.security.APIKeyHeader |
||||
|
|
||||
|
::: fastapi.security.APIKeyQuery |
||||
|
|
||||
|
## HTTP Authentication Schemes |
||||
|
|
||||
|
::: fastapi.security.HTTPBasic |
||||
|
|
||||
|
::: fastapi.security.HTTPBearer |
||||
|
|
||||
|
::: fastapi.security.HTTPDigest |
||||
|
|
||||
|
## HTTP Credentials |
||||
|
|
||||
|
::: fastapi.security.HTTPAuthorizationCredentials |
||||
|
|
||||
|
::: fastapi.security.HTTPBasicCredentials |
||||
|
|
||||
|
## OAuth2 Authentication |
||||
|
|
||||
|
::: fastapi.security.OAuth2 |
||||
|
|
||||
|
::: fastapi.security.OAuth2AuthorizationCodeBearer |
||||
|
|
||||
|
::: fastapi.security.OAuth2PasswordBearer |
||||
|
|
||||
|
## OAuth2 Password Form |
||||
|
|
||||
|
::: fastapi.security.OAuth2PasswordRequestForm |
||||
|
|
||||
|
::: fastapi.security.OAuth2PasswordRequestFormStrict |
||||
|
|
||||
|
## OAuth2 Security Scopes میں Dependencies |
||||
|
|
||||
|
::: fastapi.security.SecurityScopes |
||||
|
|
||||
|
## OpenID Connect |
||||
|
|
||||
|
::: fastapi.security.OpenIdConnect |
||||
@ -0,0 +1,13 @@ |
|||||
|
# Static Files - `StaticFiles` |
||||
|
|
||||
|
آپ `StaticFiles` class کو static files فراہم کرنے کے لیے استعمال کر سکتے ہیں، جیسے JavaScript، CSS، تصاویر، وغیرہ۔ |
||||
|
|
||||
|
اس کے بارے میں مزید پڑھیں [FastAPI دستاویزات میں Static Files](https://fastapi.tiangolo.com/tutorial/static-files/)۔ |
||||
|
|
||||
|
آپ اسے براہ راست `fastapi.staticfiles` سے import کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi.staticfiles import StaticFiles |
||||
|
``` |
||||
|
|
||||
|
::: fastapi.staticfiles.StaticFiles |
||||
@ -0,0 +1,36 @@ |
|||||
|
# Status Codes |
||||
|
|
||||
|
آپ `status` module کو `fastapi` سے import کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi import status |
||||
|
``` |
||||
|
|
||||
|
`status` براہ راست Starlette کی طرف سے فراہم کیا گیا ہے۔ |
||||
|
|
||||
|
اس میں نامزد constants (variables) کا ایک گروپ ہے جن کی قدریں integer status codes ہیں۔ |
||||
|
|
||||
|
مثال کے طور پر: |
||||
|
|
||||
|
* 200: `status.HTTP_200_OK` |
||||
|
* 403: `status.HTTP_403_FORBIDDEN` |
||||
|
* وغیرہ۔ |
||||
|
|
||||
|
یہ آپ کی app میں HTTP (اور WebSocket) status codes تک فوری رسائی کے لیے آسان ہو سکتا ہے، نام کے لیے autocompletion استعمال کرتے ہوئے بغیر integer status codes یاد رکھنے کی ضرورت کے۔ |
||||
|
|
||||
|
اس کے بارے میں مزید پڑھیں [FastAPI دستاویزات میں Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/)۔ |
||||
|
|
||||
|
## مثال |
||||
|
|
||||
|
```python |
||||
|
from fastapi import FastAPI, status |
||||
|
|
||||
|
app = FastAPI() |
||||
|
|
||||
|
|
||||
|
@app.get("/items/", status_code=status.HTTP_418_IM_A_TEAPOT) |
||||
|
def read_items(): |
||||
|
return [{"name": "Plumbus"}, {"name": "Portal Gun"}] |
||||
|
``` |
||||
|
|
||||
|
::: fastapi.status |
||||
@ -0,0 +1,13 @@ |
|||||
|
# Templating - `Jinja2Templates` |
||||
|
|
||||
|
آپ `Jinja2Templates` class کو Jinja templates render کرنے کے لیے استعمال کر سکتے ہیں۔ |
||||
|
|
||||
|
اس کے بارے میں مزید پڑھیں [FastAPI دستاویزات میں Templates](https://fastapi.tiangolo.com/advanced/templates/)۔ |
||||
|
|
||||
|
آپ اسے براہ راست `fastapi.templating` سے import کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi.templating import Jinja2Templates |
||||
|
``` |
||||
|
|
||||
|
::: fastapi.templating.Jinja2Templates |
||||
@ -0,0 +1,13 @@ |
|||||
|
# Test Client - `TestClient` |
||||
|
|
||||
|
آپ `TestClient` class کو FastAPI applications کی جانچ کرنے کے لیے استعمال کر سکتے ہیں بغیر کوئی حقیقی HTTP اور socket connection بنائے، بس FastAPI code کے ساتھ براہ راست بات چیت کر کے۔ |
||||
|
|
||||
|
اس کے بارے میں مزید پڑھیں [FastAPI دستاویزات میں Testing](https://fastapi.tiangolo.com/tutorial/testing/)۔ |
||||
|
|
||||
|
آپ اسے براہ راست `fastapi.testclient` سے import کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi.testclient import TestClient |
||||
|
``` |
||||
|
|
||||
|
::: fastapi.testclient.TestClient |
||||
@ -0,0 +1,22 @@ |
|||||
|
# `UploadFile` class |
||||
|
|
||||
|
آپ *path operation function* کے parameters کو `UploadFile` type کا define کر سکتے ہیں تاکہ request سے files وصول کی جا سکیں۔ |
||||
|
|
||||
|
آپ اسے براہ راست `fastapi` سے import کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi import UploadFile |
||||
|
``` |
||||
|
|
||||
|
::: fastapi.UploadFile |
||||
|
options: |
||||
|
members: |
||||
|
- file |
||||
|
- filename |
||||
|
- size |
||||
|
- headers |
||||
|
- content_type |
||||
|
- read |
||||
|
- write |
||||
|
- seek |
||||
|
- close |
||||
@ -0,0 +1,73 @@ |
|||||
|
# WebSockets |
||||
|
|
||||
|
WebSockets define کرتے وقت، آپ عام طور پر `WebSocket` type کا parameter declare کرتے ہیں اور اس کے ذریعے client سے ڈیٹا پڑھ سکتے ہیں اور اسے ڈیٹا بھیج سکتے ہیں۔ |
||||
|
|
||||
|
اس کے بارے میں مزید پڑھیں [FastAPI دستاویزات میں WebSockets](https://fastapi.tiangolo.com/advanced/websockets/) |
||||
|
|
||||
|
یہ Starlette کی طرف سے براہ راست فراہم کیا گیا ہے، لیکن آپ اسے `fastapi` سے import کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi import WebSocket |
||||
|
``` |
||||
|
|
||||
|
/// tip | مشورہ |
||||
|
|
||||
|
جب آپ ایسی dependencies define کرنا چاہیں جو HTTP اور WebSockets دونوں کے ساتھ مطابقت رکھتی ہوں، تو آپ `Request` یا `WebSocket` کی بجائے `HTTPConnection` لینے والا parameter define کر سکتے ہیں۔ |
||||
|
|
||||
|
/// |
||||
|
|
||||
|
::: fastapi.WebSocket |
||||
|
options: |
||||
|
members: |
||||
|
- scope |
||||
|
- app |
||||
|
- url |
||||
|
- base_url |
||||
|
- headers |
||||
|
- query_params |
||||
|
- path_params |
||||
|
- cookies |
||||
|
- client |
||||
|
- state |
||||
|
- url_for |
||||
|
- client_state |
||||
|
- application_state |
||||
|
- receive |
||||
|
- send |
||||
|
- accept |
||||
|
- receive_text |
||||
|
- receive_bytes |
||||
|
- receive_json |
||||
|
- iter_text |
||||
|
- iter_bytes |
||||
|
- iter_json |
||||
|
- send_text |
||||
|
- send_bytes |
||||
|
- send_json |
||||
|
- close |
||||
|
|
||||
|
## WebSockets - اضافی classes |
||||
|
|
||||
|
WebSockets کو سنبھالنے کے لیے اضافی classes۔ |
||||
|
|
||||
|
Starlette کی طرف سے براہ راست فراہم کی گئی ہیں، لیکن آپ انہیں `fastapi` سے import کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi.websockets import WebSocketDisconnect, WebSocketState |
||||
|
``` |
||||
|
|
||||
|
::: fastapi.websockets.WebSocketDisconnect |
||||
|
|
||||
|
جب کوئی client منقطع ہوتا ہے تو `WebSocketDisconnect` exception raise ہوتا ہے، آپ اسے catch کر سکتے ہیں۔ |
||||
|
|
||||
|
آپ اسے براہ راست `fastapi` سے import کر سکتے ہیں: |
||||
|
|
||||
|
```python |
||||
|
from fastapi import WebSocketDisconnect |
||||
|
``` |
||||
|
|
||||
|
اس کے بارے میں مزید پڑھیں [FastAPI دستاویزات میں WebSockets](https://fastapi.tiangolo.com/advanced/websockets/#handling-disconnections-and-multiple-clients) |
||||
|
|
||||
|
::: fastapi.websockets.WebSocketState |
||||
|
|
||||
|
`WebSocketState` ایک enumeration ہے جو WebSocket connection کی ممکنہ حالتوں کو ظاہر کرتا ہے۔ |
||||
@ -0,0 +1,6 @@ |
|||||
|
--- |
||||
|
hide: |
||||
|
- navigation |
||||
|
--- |
||||
|
|
||||
|
# ریلیز نوٹس |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue