Skip to content

Commit 6ad2cbb

Browse files
author
Ritik Gupta
committed
Release v0.0.1
1 parent 03d80d8 commit 6ad2cbb

File tree

7 files changed

+220
-2
lines changed

7 files changed

+220
-2
lines changed

README.md

+35-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,35 @@
1-
# find-dict-path
2-
Pythonic Dictionary path generator
1+
# Pyhtonic Dictionary Path Generator
2+
A package used to the get the Full Pythonic Dictionary Path of the Search key .
3+
4+
## How to use
5+
_After installing the package use following import:_ <br>
6+
7+
```Python
8+
from find_dict_path import Find_Dict_Path
9+
10+
search_key_from_dict = {"full name":"Brendan Stiedemann","address":{"street":{"colony":"Reinger Inc","extra_info":[{"date":"2023-05-06"},{"uuid":"6eca8033-ba89-4db2-bdb1-c2e0a4f6e0e6"},{"phone":"615-335-1131"}]}}}
11+
12+
search_key = 'phone'
13+
14+
search_path_finder_from_dict = Find_Dict_Path()
15+
16+
full_path = search_path_finder_from_dict.get_full_path(search_dict,'propEmbed')
17+
18+
print(full_path)
19+
20+
#['address']['street']['extra_info'][2]['phone']
21+
22+
```
23+
24+
_If you wants to get path in every occurrence of the list within dictionary then we can use `find_first_occurance=False` by default it is set as True _ <br>
25+
26+
```Python
27+
full_path = search_path_finder_from_dict.get_full_path(search_dict,'propEmbed',find_first_occurance=False)
28+
29+
print(full_path)
30+
31+
#['address']['street']['extra_info'][*]['phone']
32+
```
33+
34+
> **_NOTE:_** In output path [*] represent the List is present.
35+

app/__init__.py

Whitespace-only changes.

app/find_dict_path/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from find_key_in_dict import (
2+
Find_Dict_Path
3+
)
+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
from typing import List
2+
3+
4+
class Find_Dict_Path:
5+
6+
def __init__(self) -> None:
7+
self.ans=[]
8+
9+
10+
def get_full_path(self,raw_dict_list_data:dict,search_key_name:str,find_first_occurance:bool=True) -> str:
11+
self.ans=[]
12+
self.__find_full_path_of_key(raw_dict_list_data,search_key_name,find_first_occurance)
13+
return self.__get_path_formatter()
14+
15+
def __get_path_formatter(self) -> str:
16+
17+
if self.ans==[]:
18+
return "[]"
19+
20+
formatted_path=""
21+
22+
for sub_path in self.ans:
23+
if isinstance(sub_path,int) or sub_path=="*":
24+
formatted_path+=f"[{sub_path}]"
25+
else:
26+
formatted_path+=f"['{sub_path}']"
27+
28+
return formatted_path
29+
30+
def __find_full_path_of_key(self,raw_dict_list_data:dict,search_key_name:str,find_first_occurance:bool=True) -> bool:
31+
32+
if isinstance(raw_dict_list_data,list):
33+
for index,single_list_data in enumerate(raw_dict_list_data):
34+
result=self.__find_full_path_of_key(single_list_data,search_key_name,find_first_occurance)
35+
if result:
36+
self.ans.insert(0,index if find_first_occurance else "*")
37+
return True
38+
39+
if isinstance(raw_dict_list_data,dict):
40+
for key,value in raw_dict_list_data.items():
41+
if key==search_key_name:
42+
self.ans.insert(0,key)
43+
return True
44+
else:
45+
result=self.__find_full_path_of_key(value,search_key_name,find_first_occurance)
46+
if result:
47+
self.ans.insert(0,key)
48+
return True
49+
50+
return False
51+
52+

outline.md

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
## Introduction
2+
3+
- Python packaging is the most common way to share code/libraries/applications. It allows packaging of the modules, so that they can later be published and deployed by other users, either by sharing binary files, source code or by using a package manager to fetch them from online (public or private) repositories.
4+
- The recommended way to package your code is by using the built-in python library _setuptools_ which has a lot and powerful functionalities.
5+
- In this video, I ll show you how to harness some the power of _setuptools_ so that you can package and publish your code on the official python repository _PyPI._
6+
- Stay with me until the end of the video, where I will present a cool and practical alternative to a common practice most developers do, but is not needed anymore when packaging your code.
7+
8+
## Example use cases (where packaging is a must)
9+
10+
- Easier management of release versioning
11+
- Shipping and deployment becomes pretty simple
12+
- Automatic dependency management
13+
- Increase your code’s accessibility
14+
- Cloud computing
15+
- Containerizing your application
16+
17+
## Code example
18+
19+
- Brief presentation of the library itself
20+
- A library that contains various ID generators ( password, guid, valid credit card number, object id and numerical pin)
21+
- Unit tests are also included
22+
- Explain how the project is structured, folders, sub-folders because it plays important role when you install the package on the installed structure.
23+
24+
## Present setuptools
25+
26+
- _setuptools_ is a (now standard) python library that facilitates packaging python projects by enhancing the _distutils_ library.
27+
- Important keywords/parameters of _setuptools_ to be aware of:
28+
- wheel (.whl): A pre-built (zip) binary file, which is ready to be installed, that contains all the necessary information (code itself and metadata) for python package manager to install the package. To create one you should run `python setup.py bdist_wheel` within the shell. bdist stands for binary distribution.
29+
- sdist (.tar.gz) : The source code distribution equivalent to wheel. A tar file (zip) that contains the source code together with the [setup.py](http://setup.py) file, so the user can re-built it. To create a source distribution run `python setup.py sdist`
30+
- The above two commands can be combined into one, if both distributions are desired. The output will be stored within the _dist_ folder that setuptools will create in the same level with [setup.py](http://setup.py) resides.
31+
- The build folder: Contains all the source code / modules that will be distributed.
32+
- egg-info: A directory placed adjacent to the project's code and resources, that directly contains the project's metadata. Replaced by wheels. (directly from Wikipedia)
33+
- Python eggs are a way of bundling additional information with a Python project, that allows the project's dependencies to be checked and
34+
satisfied at runtime, as well as allowing projects to provide [plugins](<https://en.wikipedia.org/wiki/Plug-in_(computing)>) for other projects. (quoting wikipedia)
35+
36+
## Present [setup.py](http://setup.py)
37+
38+
- Talk about the basic parameters (the ones already in our example [setup.py](http://setup.py) file), brief explanation on what each one is responsible for.
39+
- Explain in a nutshell how to customize the parameters it needs for [setup.py](http://setup.py) to work, mostly package dir and packages that allows setuptools to automatically find all the packages in our project structure (which is explained before in code example).
40+
- Mention that _\*\*init_\*\*.py needs to be present in every directory/folder in order for it to be seen as a package directory.
41+
- Mention that an alternative to adding the parameters in [setup.py](http://setup.py) (python file) you can screate a setup.cfg (configuration file) as well. But that’s outside the scope of this video.
42+
43+
## Building and installing a package (sdist, wheel)
44+
45+
- Run [setup.py](http://setup.py) using ‘_python [setup.py](http://setup.py/) bdist_wheel sdist’_ command. Explain that this creates both source code files and binary (.whl) file.
46+
- Then install package locally by running ‘_pip install idgenerator-0.0.x-py3-none-any.whl’._ Alternatively, you can also run _pip install ._ under the directory where [setup.py](http://setup.py) lives and will install your package directly, but that doesn’t the _dist_ folder which contains all the files needed for publishing in the PyPI repository. (up to you).
47+
- Optionally, explain how to update _.gitignore_ to ignore _build, dist and .egg-info_ files.
48+
- NOTE: The current [setup.py](http://setup.py) file is configured to also install the tests within the python environment. That is not the way it should normally happen, it happens only for the purposes of this demo. We can always change that for the video if you think it should happen otherwise.
49+
50+
## Introducing PyPI
51+
52+
- Explain what PyPI is in a nutshell, how to browse/search packages and see the metadata about it (set up the ground for when you publish your package later).
53+
- Maybe a catchy point is to mention that when you _pip install anything_ you are basically fetching from PyPI (surprisingly enough some people might not know this!).
54+
- Make an account so that you can publish a package. I would recommend to make a testPyPI account [https://test.pypi.org/](https://test.pypi.org/) so that you don’t actually publish under the official repository.
55+
- Optional but good practice, explain how to configure / create _.pypirc_ file, so authentication happens automatically when uploading your package to the repository. Also good for privacy issues when making the video that your token doesn’t get compromised.
56+
57+
## Publishing the package on PyPI
58+
59+
- Make sure you have _twine_ installed. That’s a good point to run ‘_pip install .[dev]’._ Twine is declared as a development dependency, so that will install it automatically together with the package itself.
60+
- Run _twine check dist/_ ,\* you should see tests passed for both source code and wheel file.
61+
- Run ‘_twine upload — repository testpypi dist/_’ ._ Assuming you have a _.pypirc\* file configured, that should work and publish your package to the testPyPI repo.
62+
- Small detail to be aware of: If you try to publish same version name as already published, testPyPI won’t allow it and you ll get an error. (see point 7 in retrospective)
63+
- Visit your package’s webpage so that viewers can see how the package looks published.
64+
- You can also create a new environment and install the newly published package via pip. You can do the same within the existing environment but always more neat to do on a fresh environment.
65+
66+
## Further capabilities of packaging
67+
68+
- This part is totally up to you, as in how much further you want to go. Take a look at retro to see what you think is worth mentioning more extensively here. Number 4, 11 for example might be such cases.
69+
- Some interesting capabilities worth discussed for sure imo within the context of this video is _‘pip install -e .’_
70+
71+
## Hook sharing
72+
73+
- Talk about the no need of _requirements.txt_ due to the [setup.py](http://setup.py) dev option. If you did the first bullet point of Publishing the package, you can call back to it.
74+
75+
## Retrospective
76+
77+
Things to keep in mind before diving into code packaging:
78+
79+
1. How much does it make sense when you package your code? (Is your code easily re-usable/abstracted enough and ‘plug and play’ after deployment?)
80+
2. Are you packaging your code for own use (for example in different environment), or to share it easier with other developers? (Documenting it, creating a helper web-page might be a good idea, or even necessary in some cases)
81+
3. If you re planning to share your package with others, consider using a software license before. Have a look at [https://tldrlegal.com/](https://tldrlegal.com/) or [https://choosealicense.com/](https://choosealicense.com/) for understanding the most popular software licenses available.
82+
4. If the application requires extra data, should those data be incorporated in the module or linked externally (depending on size)?
83+
5. Are the code modules decoupled enough for the end user to utilize parts of the package if needed?
84+
6. Is the architecture good enough for further development and do the modules/submodules semantically make sense to be named/placed the way they are?
85+
7. To avoid the overhead of updating the package version manually every time versioning management modules might come handy (ex. bumpversion\***\*).\*\*** Plus you are avoiding publishing clashes (PyPI) that occur under a version number already published previously.
86+
8. Good practice to use as many classifiers applicable, so that it helps developers find your package easier by filtering and it provides some metadata as well. Check the available classifiers here [https://pypi.org/classifiers/](https://pypi.org/classifiers/)
87+
9. Instead of using [setup.py](http://setup.py) file (code) you can atlernatively use setup.cfg which is a configuration file instead.
88+
10. Avoid using distutils package, use always setuptools, which is an enhancement of the former.
89+
11. Always publish your code under a license. By not using any license when packaging your code you are not allowing anyone to use your code?

run.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from idgenerator import (
2+
generate_password,
3+
generate_guid,
4+
generate_credit_card_number,
5+
generate_object_id,
6+
generate_pin_number,
7+
)
8+
9+
print(generate_password(length=8))
10+
11+
print(generate_guid())
12+
13+
print(generate_credit_card_number(length=16))
14+
15+
print(str(generate_pin_number(length=4)))
16+
17+
print(generate_object_id())

setup.py

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from setuptools import find_packages, setup
2+
3+
with open("README.md", "r") as f:
4+
long_description = f.read()
5+
6+
setup(
7+
name="find_dict_path",
8+
version="0.0.1",
9+
description="An Pythonic Dictionary path generator ",
10+
package_dir={"": "app"},
11+
packages=find_packages(where="app"),
12+
long_description=long_description,
13+
long_description_content_type="text/markdown",
14+
url="https://github.com/ArjanCodes/2023-package",
15+
author="Ritik",
16+
author_email="[email protected]",
17+
license="MIT",
18+
classifiers=[
19+
"License :: OSI Approved :: MIT License",
20+
"Programming Language :: Python :: 3.10",
21+
"Operating System :: OS Independent",
22+
],
23+
python_requires=">=3.5",
24+
)

0 commit comments

Comments
 (0)