Compare commits
	
		
			10 Commits
		
	
	
		
			3766531936
			...
			build/poet
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 0c5e8e93ac | |||
| 9b0b772786 | |||
| c2875df304 | |||
| 49ab38d66c | |||
| 9918c8c413 | |||
| b50b54be34 | |||
| c3396b13ac | |||
| fa4c7eef03 | |||
| 3919519e50 | |||
| bbc0c3b976 | 
| @@ -1,2 +1,6 @@ | ||||
| venv | ||||
| dist/ | ||||
| build-docker.sh | ||||
| Dockerfile | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -3,3 +3,6 @@ | ||||
| *.egg-info | ||||
| .idea | ||||
| */__pycache__/ | ||||
| /dist/ | ||||
| build | ||||
| __pycache__ | ||||
|   | ||||
							
								
								
									
										618
									
								
								.pylintrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										618
									
								
								.pylintrc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,618 @@ | ||||
| [MAIN] | ||||
|  | ||||
| # Analyse import fallback blocks. This can be used to support both Python 2 and | ||||
| # 3 compatible code, which means that the block might have code that exists | ||||
| # only in one or another interpreter, leading to false positives when analysed. | ||||
| analyse-fallback-blocks=no | ||||
|  | ||||
| # Load and enable all available extensions. Use --list-extensions to see a list | ||||
| # all available extensions. | ||||
| #enable-all-extensions= | ||||
|  | ||||
| # In error mode, messages with a category besides ERROR or FATAL are | ||||
| # suppressed, and no reports are done by default. Error mode is compatible with | ||||
| # disabling specific errors. | ||||
| #errors-only= | ||||
|  | ||||
| # Always return a 0 (non-error) status code, even if lint errors are found. | ||||
| # This is primarily useful in continuous integration scripts. | ||||
| #exit-zero= | ||||
|  | ||||
| # A comma-separated list of package or module names from where C extensions may | ||||
| # be loaded. Extensions are loading into the active Python interpreter and may | ||||
| # run arbitrary code. | ||||
| extension-pkg-allow-list=depthai,node,cv2,events.* | ||||
|  | ||||
| # A comma-separated list of package or module names from where C extensions may | ||||
| # be loaded. Extensions are loading into the active Python interpreter and may | ||||
| # run arbitrary code. (This is an alternative name to extension-pkg-allow-list | ||||
| # for backward compatibility.) | ||||
| extension-pkg-whitelist= | ||||
|  | ||||
| # Return non-zero exit code if any of these messages/categories are detected, | ||||
| # even if score is above --fail-under value. Syntax same as enable. Messages | ||||
| # specified are enabled, while categories only check already-enabled messages. | ||||
| fail-on= | ||||
|  | ||||
| # Specify a score threshold under which the program will exit with error. | ||||
| fail-under=10 | ||||
|  | ||||
| # Interpret the stdin as a python script, whose filename needs to be passed as | ||||
| # the module_or_package argument. | ||||
| #from-stdin= | ||||
|  | ||||
| # Files or directories to be skipped. They should be base names, not paths. | ||||
| ignore=CVS | ||||
|  | ||||
| # Add files or directories matching the regular expressions patterns to the | ||||
| # ignore-list. The regex matches against paths and can be in Posix or Windows | ||||
| # format. Because '\' represents the directory delimiter on Windows systems, it | ||||
| # can't be used as an escape character. | ||||
| ignore-paths= | ||||
|  | ||||
| # Files or directories matching the regular expression patterns are skipped. | ||||
| # The regex matches against base names, not paths. The default value ignores | ||||
| # Emacs file locks | ||||
| ignore-patterns=^\.#,test_.*?py | ||||
|  | ||||
| # List of module names for which member attributes should not be checked | ||||
| # (useful for modules/projects where namespaces are manipulated during runtime | ||||
| # and thus existing member attributes cannot be deduced by static analysis). It | ||||
| # supports qualified module names, as well as Unix pattern matching. | ||||
| ignored-modules= | ||||
|  | ||||
| # Python code to execute, usually for sys.path manipulation such as | ||||
| # pygtk.require(). | ||||
| #init-hook= | ||||
|  | ||||
| # Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the | ||||
| # number of processors available to use, and will cap the count on Windows to | ||||
| # avoid hangs. | ||||
| jobs=1 | ||||
|  | ||||
| # Control the amount of potential inferred values when inferring a single | ||||
| # object. This can help the performance when dealing with large functions or | ||||
| # complex, nested conditions. | ||||
| limit-inference-results=100 | ||||
|  | ||||
| # List of plugins (as comma separated values of python module names) to load, | ||||
| # usually to register additional checkers. | ||||
| load-plugins= | ||||
|  | ||||
| # Pickle collected data for later comparisons. | ||||
| persistent=yes | ||||
|  | ||||
| # Minimum Python version to use for version dependent checks. Will default to | ||||
| # the version used to run pylint. | ||||
| py-version=3.10 | ||||
|  | ||||
| # Discover python modules and packages in the file system subtree. | ||||
| recursive=yes | ||||
|  | ||||
| # When enabled, pylint would attempt to guess common misconfiguration and emit | ||||
| # user-friendly hints instead of false-positive error messages. | ||||
| suggestion-mode=yes | ||||
|  | ||||
| # Allow loading of arbitrary C extensions. Extensions are imported into the | ||||
| # active Python interpreter and may run arbitrary code. | ||||
| unsafe-load-any-extension=no | ||||
|  | ||||
| # In verbose mode, extra non-checker-related info will be displayed. | ||||
| #verbose= | ||||
|  | ||||
|  | ||||
| [REPORTS] | ||||
|  | ||||
| # Python expression which should return a score less than or equal to 10. You | ||||
| # have access to the variables 'fatal', 'error', 'warning', 'refactor', | ||||
| # 'convention', and 'info' which contain the number of messages in each | ||||
| # category, as well as 'statement' which is the total number of statements | ||||
| # analyzed. This score is used by the global evaluation report (RP0004). | ||||
| evaluation=max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)) | ||||
|  | ||||
| # Template used to display messages. This is a python new-style format string | ||||
| # used to format the message information. See doc for all details. | ||||
| msg-template= | ||||
|  | ||||
| # Set the output format. Available formats are text, parseable, colorized, json | ||||
| # and msvs (visual studio). You can also give a reporter class, e.g. | ||||
| # mypackage.mymodule.MyReporterClass. | ||||
| #output-format= | ||||
|  | ||||
| # Tells whether to display a full report or only the messages. | ||||
| reports=no | ||||
|  | ||||
| # Activate the evaluation score. | ||||
| score=yes | ||||
|  | ||||
|  | ||||
| [MESSAGES CONTROL] | ||||
|  | ||||
| # Only show warnings with the listed confidence levels. Leave empty to show | ||||
| # all. Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE, | ||||
| # UNDEFINED. | ||||
| confidence=HIGH, | ||||
|            CONTROL_FLOW, | ||||
|            INFERENCE, | ||||
|            INFERENCE_FAILURE, | ||||
|            UNDEFINED | ||||
|  | ||||
| # Disable the message, report, category or checker with the given id(s). You | ||||
| # can either give multiple identifiers separated by comma (,) or put this | ||||
| # option multiple times (only on the command line, not in the configuration | ||||
| # file where it should appear only once). You can also use "--disable=all" to | ||||
| # disable everything first and then re-enable specific checks. For example, if | ||||
| # you want to run only the similarities checker, you can use "--disable=all | ||||
| # --enable=similarities". If you want to run only the classes checker, but have | ||||
| # no Warning level messages displayed, use "--disable=all --enable=classes | ||||
| # --disable=W". | ||||
| disable=raw-checker-failed, | ||||
|         bad-inline-option, | ||||
|         locally-disabled, | ||||
|         file-ignored, | ||||
|         suppressed-message, | ||||
|         useless-suppression, | ||||
|         deprecated-pragma, | ||||
|         use-symbolic-message-instead | ||||
|  | ||||
| # Enable the message, report, category or checker with the given id(s). You can | ||||
| # either give multiple identifier separated by comma (,) or put this option | ||||
| # multiple time (only on the command line, not in the configuration file where | ||||
| # it should appear only once). See also the "--disable" option for examples. | ||||
| enable=c-extension-no-member | ||||
|  | ||||
|  | ||||
| [LOGGING] | ||||
|  | ||||
| # The type of string formatting that logging methods do. `old` means using % | ||||
| # formatting, `new` is for `{}` formatting. | ||||
| logging-format-style=old | ||||
|  | ||||
| # Logging modules to check that the string format arguments are in logging | ||||
| # function parameter format. | ||||
| logging-modules=logging | ||||
|  | ||||
|  | ||||
| [SPELLING] | ||||
|  | ||||
| # Limits count of emitted suggestions for spelling mistakes. | ||||
| max-spelling-suggestions=4 | ||||
|  | ||||
| # Spelling dictionary name. Available dictionaries: none. To make it work, | ||||
| # install the 'python-enchant' package. | ||||
| spelling-dict= | ||||
|  | ||||
| # List of comma separated words that should be considered directives if they | ||||
| # appear at the beginning of a comment and should not be checked. | ||||
| spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy: | ||||
|  | ||||
| # List of comma separated words that should not be checked. | ||||
| spelling-ignore-words= | ||||
|  | ||||
| # A path to a file that contains the private dictionary; one word per line. | ||||
| spelling-private-dict-file= | ||||
|  | ||||
| # Tells whether to store unknown words to the private dictionary (see the | ||||
| # --spelling-private-dict-file option) instead of raising a message. | ||||
| spelling-store-unknown-words=no | ||||
|  | ||||
|  | ||||
| [MISCELLANEOUS] | ||||
|  | ||||
| # List of note tags to take in consideration, separated by a comma. | ||||
| notes=FIXME, | ||||
|       XXX, | ||||
|       TODO | ||||
|  | ||||
| # Regular expression of note tags to take in consideration. | ||||
| notes-rgx= | ||||
|  | ||||
|  | ||||
| [TYPECHECK] | ||||
|  | ||||
| # List of decorators that produce context managers, such as | ||||
| # contextlib.contextmanager. Add to this list to register other decorators that | ||||
| # produce valid context managers. | ||||
| contextmanager-decorators=contextlib.contextmanager | ||||
|  | ||||
| # List of members which are set dynamically and missed by pylint inference | ||||
| # system, and so shouldn't trigger E1101 when accessed. Python regular | ||||
| # expressions are accepted. | ||||
| generated-members=cv2,events.events_pb2,depthai.*,dai.* | ||||
|  | ||||
| # Tells whether to warn about missing members when the owner of the attribute | ||||
| # is inferred to be None. | ||||
| ignore-none=yes | ||||
|  | ||||
| # This flag controls whether pylint should warn about no-member and similar | ||||
| # checks whenever an opaque object is returned when inferring. The inference | ||||
| # can return multiple potential results while evaluating a Python object, but | ||||
| # some branches might not be evaluated, which results in partial inference. In | ||||
| # that case, it might be useful to still emit no-member and other checks for | ||||
| # the rest of the inferred objects. | ||||
| ignore-on-opaque-inference=yes | ||||
|  | ||||
| # List of symbolic message names to ignore for Mixin members. | ||||
| ignored-checks-for-mixins=no-member, | ||||
|                           not-async-context-manager, | ||||
|                           not-context-manager, | ||||
|                           attribute-defined-outside-init | ||||
|  | ||||
| # List of class names for which member attributes should not be checked (useful | ||||
| # for classes with dynamically set attributes). This supports the use of | ||||
| # qualified names. | ||||
| ignored-classes=optparse.Values,thread._local,_thread._local,argparse.Namespace | ||||
|  | ||||
| # Show a hint with possible names when a member name was not found. The aspect | ||||
| # of finding the hint is based on edit distance. | ||||
| missing-member-hint=yes | ||||
|  | ||||
| # The minimum edit distance a name should have in order to be considered a | ||||
| # similar match for a missing member name. | ||||
| missing-member-hint-distance=1 | ||||
|  | ||||
| # The total number of similar names that should be taken in consideration when | ||||
|  | ||||
| missing-member-max-choices=1 | ||||
|  | ||||
| # Regex pattern to define which classes are considered mixins. | ||||
| mixin-class-rgx=.*[Mm]ixin | ||||
|  | ||||
| # List of decorators that change the signature of a decorated function. | ||||
| signature-mutators= | ||||
|  | ||||
|  | ||||
| [CLASSES] | ||||
|  | ||||
| # Warn about protected attribute access inside special methods | ||||
| check-protected-access-in-special-methods=no | ||||
|  | ||||
| # List of method names used to declare (i.e. assign) instance attributes. | ||||
| defining-attr-methods=__init__, | ||||
|                       __new__, | ||||
|                       setUp, | ||||
|                       __post_init__ | ||||
|  | ||||
| # List of member names, which should be excluded from the protected access | ||||
| # warning. | ||||
| exclude-protected=_asdict, | ||||
|                   _fields, | ||||
|                   _replace, | ||||
|                   _source, | ||||
|                   _make | ||||
|  | ||||
| # List of valid names for the first argument in a class method. | ||||
| valid-classmethod-first-arg=cls | ||||
|  | ||||
| # List of valid names for the first argument in a metaclass class method. | ||||
| valid-metaclass-classmethod-first-arg=cls | ||||
|  | ||||
|  | ||||
| [VARIABLES] | ||||
|  | ||||
| # List of additional names supposed to be defined in builtins. Remember that | ||||
| # you should avoid defining new builtins when possible. | ||||
| additional-builtins= | ||||
|  | ||||
| # Tells whether unused global variables should be treated as a violation. | ||||
| allow-global-unused-variables=yes | ||||
|  | ||||
| # List of names allowed to shadow builtins | ||||
| allowed-redefined-builtins= | ||||
|  | ||||
| # List of strings which can identify a callback function by name. A callback | ||||
| # name must start or end with one of those strings. | ||||
| callbacks=cb_, | ||||
|           _cb | ||||
|  | ||||
| # A regular expression matching the name of dummy variables (i.e. expected to | ||||
| # not be used). | ||||
| dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ | ||||
|  | ||||
| # Argument names that match this expression will be ignored. | ||||
| ignored-argument-names=_.*|^ignored_|^unused_ | ||||
|  | ||||
| # Tells whether we should check for unused import in __init__ files. | ||||
| init-import=no | ||||
|  | ||||
| # List of qualified module names which can have objects that can redefine | ||||
| # builtins. | ||||
| redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io | ||||
|  | ||||
|  | ||||
| [FORMAT] | ||||
|  | ||||
| # Expected format of line ending, e.g. empty (any line ending), LF or CRLF. | ||||
| expected-line-ending-format= | ||||
|  | ||||
| # Regexp for a line that is allowed to be longer than the limit. | ||||
| ignore-long-lines=^\s*(# )?<?https?://\S+>?$ | ||||
|  | ||||
| # Number of spaces of indent required inside a hanging or continued line. | ||||
| indent-after-paren=4 | ||||
|  | ||||
| # String used as indentation unit. This is usually "    " (4 spaces) or "\t" (1 | ||||
| # tab). | ||||
| indent-string='    ' | ||||
|  | ||||
| # Maximum number of characters on a single line. | ||||
| max-line-length=120 | ||||
|  | ||||
| # Maximum number of lines in a module. | ||||
| max-module-lines=1000 | ||||
|  | ||||
| # Allow the body of a class to be on the same line as the declaration if body | ||||
| # contains single statement. | ||||
| single-line-class-stmt=no | ||||
|  | ||||
| # Allow the body of an if to be on the same line as the test if there is no | ||||
| # else. | ||||
| single-line-if-stmt=no | ||||
|  | ||||
|  | ||||
| [IMPORTS] | ||||
|  | ||||
| # List of modules that can be imported at any level, not just the top level | ||||
| # one. | ||||
| allow-any-import-level= | ||||
|  | ||||
| # Allow wildcard imports from modules that define __all__. | ||||
| allow-wildcard-with-all=no | ||||
|  | ||||
| # Deprecated modules which should not be used, separated by a comma. | ||||
| deprecated-modules= | ||||
|  | ||||
| # Output a graph (.gv or any supported image format) of external dependencies | ||||
| # to the given file (report RP0402 must not be disabled). | ||||
| ext-import-graph= | ||||
|  | ||||
| # Output a graph (.gv or any supported image format) of all (i.e. internal and | ||||
| # external) dependencies to the given file (report RP0402 must not be | ||||
| # disabled). | ||||
| import-graph= | ||||
|  | ||||
| # Output a graph (.gv or any supported image format) of internal dependencies | ||||
| # to the given file (report RP0402 must not be disabled). | ||||
| int-import-graph= | ||||
|  | ||||
| # Force import order to recognize a module as part of the standard | ||||
| # compatibility libraries. | ||||
| known-standard-library= | ||||
|  | ||||
| # Force import order to recognize a module as part of a third party library. | ||||
| known-third-party=enchant | ||||
|  | ||||
| # Couples of modules and preferred modules, separated by a comma. | ||||
| preferred-modules= | ||||
|  | ||||
|  | ||||
| [METHOD_ARGS] | ||||
|  | ||||
| # List of qualified names (i.e., library.method) which require a timeout | ||||
| # parameter e.g. 'requests.api.get,requests.api.post' | ||||
| timeout-methods=requests.api.delete,requests.api.get,requests.api.head,requests.api.options,requests.api.patch,requests.api.post,requests.api.put,requests.api.request | ||||
|  | ||||
|  | ||||
| [EXCEPTIONS] | ||||
|  | ||||
| # Exceptions that will emit a warning when caught. | ||||
| overgeneral-exceptions=BaseException, | ||||
|                        Exception | ||||
|  | ||||
|  | ||||
| [REFACTORING] | ||||
|  | ||||
| # Maximum number of nested blocks for function / method body | ||||
| max-nested-blocks=5 | ||||
|  | ||||
| # Complete name of functions that never returns. When checking for | ||||
| # inconsistent-return-statements if a never returning function is called then | ||||
| # it will be considered as an explicit return statement and no message will be | ||||
| # printed. | ||||
| never-returning-functions=sys.exit,argparse.parse_error | ||||
|  | ||||
|  | ||||
| [SIMILARITIES] | ||||
|  | ||||
| # Comments are removed from the similarity computation | ||||
| ignore-comments=yes | ||||
|  | ||||
| # Docstrings are removed from the similarity computation | ||||
| ignore-docstrings=yes | ||||
|  | ||||
| # Imports are removed from the similarity computation | ||||
| ignore-imports=yes | ||||
|  | ||||
| # Signatures are removed from the similarity computation | ||||
| ignore-signatures=yes | ||||
|  | ||||
| # Minimum lines number of a similarity. | ||||
| min-similarity-lines=4 | ||||
|  | ||||
|  | ||||
| [DESIGN] | ||||
|  | ||||
| # List of regular expressions of class ancestor names to ignore when counting | ||||
| # public methods (see R0903) | ||||
| exclude-too-few-public-methods= | ||||
|  | ||||
| # List of qualified class names to ignore when counting class parents (see | ||||
| # R0901) | ||||
| ignored-parents= | ||||
|  | ||||
| # Maximum number of arguments for function / method. | ||||
| max-args=5 | ||||
|  | ||||
| # Maximum number of attributes for a class (see R0902). | ||||
| max-attributes=7 | ||||
|  | ||||
| # Maximum number of boolean expressions in an if statement (see R0916). | ||||
| max-bool-expr=5 | ||||
|  | ||||
| # Maximum number of branch for function / method body. | ||||
| max-branches=12 | ||||
|  | ||||
| # Maximum number of locals for function / method body. | ||||
| max-locals=15 | ||||
|  | ||||
| # Maximum number of parents for a class (see R0901). | ||||
| max-parents=7 | ||||
|  | ||||
| # Maximum number of public methods for a class (see R0904). | ||||
| max-public-methods=20 | ||||
|  | ||||
| # Maximum number of return / yield for function / method body. | ||||
| max-returns=6 | ||||
|  | ||||
| # Maximum number of statements in function / method body. | ||||
| max-statements=50 | ||||
|  | ||||
| # Minimum number of public methods for a class (see R0903). | ||||
| min-public-methods=1 | ||||
|  | ||||
|  | ||||
| [STRING] | ||||
|  | ||||
| # This flag controls whether inconsistent-quotes generates a warning when the | ||||
| # character used as a quote delimiter is used inconsistently within a module. | ||||
| check-quote-consistency=no | ||||
|  | ||||
| # This flag controls whether the implicit-str-concat should generate a warning | ||||
| # on implicit string concatenation in sequences defined over several lines. | ||||
| check-str-concat-over-line-jumps=no | ||||
|  | ||||
|  | ||||
| [BASIC] | ||||
|  | ||||
| # Naming style matching correct argument names. | ||||
| argument-naming-style=snake_case | ||||
|  | ||||
| # Regular expression matching correct argument names. Overrides argument- | ||||
| # naming-style. If left empty, argument names will be checked with the set | ||||
| # naming style. | ||||
| #argument-rgx= | ||||
|  | ||||
| # Naming style matching correct attribute names. | ||||
| attr-naming-style=snake_case | ||||
|  | ||||
| # Regular expression matching correct attribute names. Overrides attr-naming- | ||||
| # style. If left empty, attribute names will be checked with the set naming | ||||
| # style. | ||||
| #attr-rgx= | ||||
|  | ||||
| # Bad variable names which should always be refused, separated by a comma. | ||||
| bad-names=foo, | ||||
|           bar, | ||||
|           baz, | ||||
|           toto, | ||||
|           tutu, | ||||
|           tata | ||||
|  | ||||
| # Bad variable names regexes, separated by a comma. If names match any regex, | ||||
| # they will always be refused | ||||
| bad-names-rgxs= | ||||
|  | ||||
| # Naming style matching correct class attribute names. | ||||
| class-attribute-naming-style=any | ||||
|  | ||||
| # Regular expression matching correct class attribute names. Overrides class- | ||||
| # attribute-naming-style. If left empty, class attribute names will be checked | ||||
| # with the set naming style. | ||||
| #class-attribute-rgx= | ||||
|  | ||||
| # Naming style matching correct class constant names. | ||||
| class-const-naming-style=UPPER_CASE | ||||
|  | ||||
| # Regular expression matching correct class constant names. Overrides class- | ||||
| # const-naming-style. If left empty, class constant names will be checked with | ||||
| # the set naming style. | ||||
| #class-const-rgx= | ||||
|  | ||||
| # Naming style matching correct class names. | ||||
| class-naming-style=PascalCase | ||||
|  | ||||
| # Regular expression matching correct class names. Overrides class-naming- | ||||
| # style. If left empty, class names will be checked with the set naming style. | ||||
| #class-rgx= | ||||
|  | ||||
| # Naming style matching correct constant names. | ||||
| const-naming-style=UPPER_CASE | ||||
|  | ||||
| # Regular expression matching correct constant names. Overrides const-naming- | ||||
| # style. If left empty, constant names will be checked with the set naming | ||||
| # style. | ||||
| #const-rgx= | ||||
|  | ||||
| # Minimum line length for functions/classes that require docstrings, shorter | ||||
| # ones are exempt. | ||||
| docstring-min-length=-1 | ||||
|  | ||||
| # Naming style matching correct function names. | ||||
| function-naming-style=snake_case | ||||
|  | ||||
| # Regular expression matching correct function names. Overrides function- | ||||
| # naming-style. If left empty, function names will be checked with the set | ||||
| # naming style. | ||||
| #function-rgx= | ||||
|  | ||||
| # Good variable names which should always be accepted, separated by a comma. | ||||
| good-names=i, | ||||
|            j, | ||||
|            k, | ||||
|            ex, | ||||
|            Run, | ||||
|            _ | ||||
|  | ||||
| # Good variable names regexes, separated by a comma. If names match any regex, | ||||
| # they will always be accepted | ||||
| good-names-rgxs= | ||||
|  | ||||
| # Include a hint for the correct naming format with invalid-name. | ||||
| include-naming-hint=no | ||||
|  | ||||
| # Naming style matching correct inline iteration names. | ||||
| inlinevar-naming-style=any | ||||
|  | ||||
| # Regular expression matching correct inline iteration names. Overrides | ||||
| # inlinevar-naming-style. If left empty, inline iteration names will be checked | ||||
| # with the set naming style. | ||||
| #inlinevar-rgx= | ||||
|  | ||||
| # Naming style matching correct method names. | ||||
| method-naming-style=snake_case | ||||
|  | ||||
| # Regular expression matching correct method names. Overrides method-naming- | ||||
| # style. If left empty, method names will be checked with the set naming style. | ||||
| #method-rgx= | ||||
|  | ||||
| # Naming style matching correct module names. | ||||
| module-naming-style=snake_case | ||||
|  | ||||
| # Regular expression matching correct module names. Overrides module-naming- | ||||
| # style. If left empty, module names will be checked with the set naming style. | ||||
| #module-rgx= | ||||
|  | ||||
| # Colon-delimited sets of names that determine each other's naming style when | ||||
| # the name regexes allow several styles. | ||||
| name-group= | ||||
|  | ||||
| # Regular expression which should only match function or class names that do | ||||
| # not require a docstring. | ||||
| no-docstring-rgx=^_ | ||||
|  | ||||
| # List of decorators that produce properties, such as abc.abstractproperty. Add | ||||
| # to this list to register other decorators that produce valid properties. | ||||
| # These decorators are taken in consideration only for invalid-name. | ||||
| property-classes=abc.abstractproperty | ||||
|  | ||||
| # Regular expression matching correct type variable names. If left empty, type | ||||
| # variable names will be checked with the set naming style. | ||||
| #typevar-rgx= | ||||
|  | ||||
| # Naming style matching correct variable names. | ||||
| variable-naming-style=snake_case | ||||
|  | ||||
| # Regular expression matching correct variable names. Overrides variable- | ||||
| # naming-style. If left empty, variable names will be checked with the set | ||||
| # naming style. | ||||
| #variable-rgx= | ||||
							
								
								
									
										48
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								Dockerfile
									
									
									
									
									
								
							| @@ -1,35 +1,37 @@ | ||||
| FROM docker.io/library/python:3.9-slim AS model | ||||
|  | ||||
| RUN python3 -m pip install blobconverter | ||||
|  | ||||
| RUN mkdir -p /models | ||||
|  | ||||
| RUN blobconverter --zoo-name mobile_object_localizer_192x192 --zoo-type depthai --shaves 6 --version 2021.4 --output-dir /models || echo "" | ||||
| RUN ls /models | ||||
| ####### | ||||
| FROM docker.io/library/python:3.9-slim | ||||
| FROM docker.io/library/python:3.10-slim as base | ||||
|  | ||||
| # Configure piwheels repo to use pre-compiled numpy wheels for arm | ||||
| RUN echo -n "[global]\nextra-index-url=https://www.piwheels.org/simple\n" >> /etc/pip.conf | ||||
|  | ||||
| RUN apt-get update && apt-get install -y libgl1 libglib2.0-0 | ||||
|  | ||||
| RUN pip3 install numpy | ||||
| ################# | ||||
| FROM base as model-builder | ||||
|  | ||||
| RUN python3 -m pip install blobconverter | ||||
|  | ||||
| RUN mkdir -p /models | ||||
|  | ||||
| RUN blobconverter --zoo-name mobile_object_localizer_192x192 --zoo-type depthai --shaves 6 --version 2021.4 --output-dir /models || echo "" | ||||
|  | ||||
| ################# | ||||
| FROM base as builder | ||||
|  | ||||
| RUN apt-get install -y git && \ | ||||
|     pip3 install poetry==1.2.0 && \ | ||||
|     poetry self add "poetry-dynamic-versioning[plugin]" | ||||
| ADD . . | ||||
|  | ||||
| RUN poetry build | ||||
|  | ||||
| ################# | ||||
| FROM base | ||||
|  | ||||
| RUN mkdir /models | ||||
| COPY --from=model-builder /models/mobile_object_localizer_192x192_openvino_2021.4_6shave.blob /models/mobile_object_localizer_192x192_openvino_2021.4_6shave.blob | ||||
|  | ||||
| COPY --from=model /models/mobile_object_localizer_192x192_openvino_2021.4_6shave.blob /models/mobile_object_localizer_192x192_openvino_2021.4_6shave.blob | ||||
| ADD requirements.txt requirements.txt | ||||
|  | ||||
| RUN pip3 install -r requirements.txt | ||||
|  | ||||
| ADD events events | ||||
| ADD camera camera | ||||
| ADD setup.cfg setup.cfg | ||||
| ADD setup.py setup.py | ||||
|  | ||||
| ENV PYTHON_EGG_CACHE=/tmp/cache | ||||
| RUN python3 setup.py install | ||||
| COPY --from=builder dist/*.whl /tmp/ | ||||
| RUN pip3 install /tmp/*whl | ||||
|  | ||||
| WORKDIR /tmp | ||||
| USER 1234 | ||||
|   | ||||
| @@ -2,11 +2,11 @@ | ||||
|  | ||||
| IMAGE_NAME=robocar-oak-camera | ||||
| TAG=$(git describe) | ||||
| FULL_IMAGE_NAME=docker.io/cyrilix/${IMAGE_NAME}:${TAG} | ||||
| FULL_IMAGE_NAME=git.cyrilix.bzh/robocars/${IMAGE_NAME}:${TAG} | ||||
| PLATFORM="linux/amd64,linux/arm64" | ||||
| #PLATFORM="linux/amd64,linux/arm64,linux/arm/v7" | ||||
|  | ||||
| podman build . --platform "${PLATFORM}" --manifest "${IMAGE_NAME}:${TAG}" | ||||
| podman manifest push --format v2s2 "localhost/${IMAGE_NAME}:${TAG}" "docker://${FULL_IMAGE_NAME}" | ||||
| podman manifest push --all --format v2s2 "localhost/${IMAGE_NAME}:${TAG}" "docker://${FULL_IMAGE_NAME}" | ||||
|  | ||||
| printf "\nImage %s published" "docker://${FULL_IMAGE_NAME}" | ||||
|   | ||||
							
								
								
									
										133
									
								
								camera/cli.py
									
									
									
									
									
								
							
							
						
						
									
										133
									
								
								camera/cli.py
									
									
									
									
									
								
							| @@ -1,77 +1,114 @@ | ||||
| """ | ||||
| Publish data from oak-lite device | ||||
|  | ||||
| Usage: rc-oak-camera [-u USERNAME | --mqtt-username=USERNAME] [--mqtt-password=PASSWORD] \ | ||||
|     [--mqtt-broker-host=HOSTNAME] [--mqtt-broker-port=PORT] \ | ||||
|     [--mqtt-topic-robocar-oak-camera="TOPIC_CAMERA"] [--mqtt-topic-robocar-objects="TOPIC_OBJECTS"] \ | ||||
|     [--mqtt-client-id=CLIENT_ID] \ | ||||
|     [-H IMG_HEIGHT | --image-height=IMG_HEIGHT] [-W IMG_WIDTH | --image-width=IMG_width] \ | ||||
|     [-t OBJECTS_THRESHOLD | --objects-threshold=OBJECTS_THRESHOLD] | ||||
|  | ||||
| Options: | ||||
| -h --help                                               Show this screen. | ||||
| -u USERID --mqtt-username=USERNAME                      MQTT user | ||||
| -p PASSWORD --mqtt-password=PASSWORD                    MQTT password | ||||
| -b HOSTNAME --mqtt-broker-host=HOSTNAME                 MQTT broker host | ||||
| -P HOSTNAME --mqtt-broker-port=PORT                     MQTT broker port | ||||
| -C CLIENT_ID --mqtt-client-id=CLIENT_ID                 MQTT client id | ||||
| -c TOPIC_CAMERA --mqtt-topic-robocar-oak-camera=TOPIC_CAMERA        MQTT topic where to publish robocar-oak-camera frames | ||||
| -o TOPIC_OBJECTS --mqtt-topic-robocar-objects=TOPIC_OBJECTS         MQTT topic where to publish objects detection results | ||||
| -H IMG_HEIGHT --image-height=IMG_HEIGHT                 IMG_HEIGHT image height | ||||
| -W IMG_WIDTH --image-width=IMG_width                    IMG_WIDTH image width | ||||
| -t OBJECTS_THRESHOLD --objects-threshold=OBJECTS_THRESHOLD    OBJECTS_THRESHOLD threshold to filter objects detected | ||||
| Mqtt gateway for oak-lite device | ||||
| """ | ||||
| import argparse | ||||
| import logging | ||||
| import os | ||||
| from . import depthai as cam | ||||
| from docopt import docopt | ||||
| import signal | ||||
|  | ||||
| import paho.mqtt.client as mqtt | ||||
|  | ||||
| from . import depthai as cam | ||||
|  | ||||
| logger = logging.getLogger(__name__) | ||||
| logging.basicConfig(level=logging.INFO) | ||||
|  | ||||
| default_client_id = "robocar-depthai" | ||||
| _DEFAULT_CLIENT_ID = "robocar-depthai" | ||||
|  | ||||
|  | ||||
| def init_mqtt_client(broker_host: str, broker_port, user: str, password: str, client_id: str) -> mqtt.Client: | ||||
| def _parse_args_cli() -> argparse.Namespace: | ||||
|     parser = argparse.ArgumentParser() | ||||
|     parser.add_argument("-u", "--mqtt-username", | ||||
|                         help="MQTT user", | ||||
|                         default=_get_env_value("MQTT_USERNAME", "")) | ||||
|     parser.add_argument("-p", "--mqtt-password", | ||||
|                         help="MQTT password", | ||||
|                         default=_get_env_value("MQTT_PASSWORD", "")) | ||||
|     parser.add_argument("-b", "--mqtt-broker-host", | ||||
|                         help="MQTT broker host", | ||||
|                         default=_get_env_value("MQTT_BROKER_HOST", "localhost")) | ||||
|     parser.add_argument("-P", "--mqtt-broker-port", | ||||
|                         help="MQTT broker port", | ||||
|                         type=int, | ||||
|                         default=_get_env_int_value("MQTT_BROKER_PORT", 1883)) | ||||
|     parser.add_argument("-C", "--mqtt-client-id", | ||||
|                         help="MQTT client id", | ||||
|                         default=_get_env_value("MQTT_CLIENT_ID", _DEFAULT_CLIENT_ID)) | ||||
|     parser.add_argument("-c", "--mqtt-topic-robocar-oak-camera", | ||||
|                         help="MQTT topic where to publish robocar-oak-camera frames", | ||||
|                         default=_get_env_value("MQTT_TOPIC_CAMERA", "/oak/camera_rgb")) | ||||
|     parser.add_argument("-o", "---mqtt-topic-robocar-objects", | ||||
|                         help="MQTT topic where to publish objects detection results", | ||||
|                         default=_get_env_value("MQTT_TOPIC_OBJECTS", "/objects")) | ||||
|     parser.add_argument("-t", "--objects-threshold", | ||||
|                         help="threshold to filter detected objects", | ||||
|                         type=float, | ||||
|                         default=_get_env_float_value("OBJECTS_THRESHOLD", 0.2)) | ||||
|     parser.add_argument("-H", "--image-height", help="image height", | ||||
|                         type=int, | ||||
|                         default=_get_env_int_value("IMAGE_HEIGHT", 120)) | ||||
|     parser.add_argument("-W", "--image-width", help="image width", | ||||
|                         type=int, | ||||
|                         default=_get_env_int_value("IMAGE_WIDTH", 126)) | ||||
|     args = parser.parse_args() | ||||
|     return args | ||||
|  | ||||
|  | ||||
| def _init_mqtt_client(broker_host: str, broker_port, user: str, password: str, client_id: str) -> mqtt.Client: | ||||
|     logger.info("Start part.py-robocar-oak-camera") | ||||
|     client = mqtt.Client(client_id=client_id, clean_session=True, userdata=None, protocol=mqtt.MQTTv311) | ||||
|  | ||||
|     client.username_pw_set(user, password) | ||||
|     logger.info("Connect to mqtt broker "+ broker_host) | ||||
|     logger.info("Connect to mqtt broker %s", broker_host) | ||||
|     client.connect(host=broker_host, port=broker_port, keepalive=60) | ||||
|     logger.info("Connected to mqtt broker") | ||||
|     return client | ||||
|  | ||||
|  | ||||
| def execute_from_command_line(): | ||||
| def execute_from_command_line() -> None: | ||||
|     """ | ||||
|     Cli entrypoint | ||||
|     :return: | ||||
|     """ | ||||
|     logging.basicConfig(level=logging.INFO) | ||||
|  | ||||
|     args = docopt(__doc__) | ||||
|     args = _parse_args_cli() | ||||
|  | ||||
|     client = init_mqtt_client(broker_host=get_default_value(args["--mqtt-broker-host"], "MQTT_BROKER_HOST", "localhost"), | ||||
|                               broker_port=int(get_default_value(args["--mqtt-broker-port"], "MQTT_BROKER_PORT", "1883")), | ||||
|                               user=get_default_value(args["--mqtt-username"], "MQTT_USERNAME", ""), | ||||
|                               password=get_default_value(args["--mqtt-password"], "MQTT_PASSWORD", ""), | ||||
|                               client_id=get_default_value(args["--mqtt-client-id"], "MQTT_CLIENT_ID", | ||||
|                                                           default_client_id), | ||||
|                               ) | ||||
|     frame_topic = get_default_value(args["--mqtt-topic-robocar-oak-camera"], "MQTT_TOPIC_CAMERA", "/oak/camera_rgb") | ||||
|     objects_topic = get_default_value(args["--mqtt-topic-robocar-objects"], "MQTT_TOPIC_OBJECTS", "/objects") | ||||
|     client = _init_mqtt_client(broker_host=args.mqtt_broker_host, | ||||
|                                broker_port=args.mqtt_broker_port, | ||||
|                                user=args.mqtt_username, | ||||
|                                password=args.mqtt_password, | ||||
|                                client_id=args.mqtt_client_id, | ||||
|                                ) | ||||
|     frame_processor = cam.FrameProcessor(mqtt_client=client, frame_topic=args.mqtt_topic_robocar_oak_camera) | ||||
|     object_processor = cam.ObjectProcessor(mqtt_client=client, | ||||
|                                            objects_topic=args.mqtt_topic_robocar_objects, | ||||
|                                            objects_threshold=args.objects_threshold) | ||||
|  | ||||
|     frame_processor = cam.FramePublisher(mqtt_client=client, | ||||
|                                          frame_topic=frame_topic, | ||||
|                                          objects_topic=objects_topic, | ||||
|                                          objects_threshold=float(get_default_value(args["--objects-threshold"], | ||||
|                                                                                    "OBJECTS_THRESHOLD", 0.2)), | ||||
|                                          img_width=int(get_default_value(args["--image-width"], "IMAGE_WIDTH", 160)), | ||||
|                                          img_height=int(get_default_value(args["--image-height"], "IMAGE_HEIGHT", 120))) | ||||
|     frame_processor.run() | ||||
|     pipeline_controller = cam.PipelineController(img_width=args.image_width, | ||||
|                                                  img_height=args.image_height, | ||||
|                                                  frame_processor=frame_processor, | ||||
|                                                  object_processor=object_processor) | ||||
|  | ||||
|     def sigterm_handler(): | ||||
|         logger.info("exit on SIGTERM") | ||||
|         pipeline_controller.stop() | ||||
|  | ||||
|     signal.signal(signal.SIGTERM, sigterm_handler) | ||||
|     pipeline_controller.run() | ||||
|  | ||||
|  | ||||
| def get_default_value(value, env_var: str, default_value) -> str: | ||||
|     if value: | ||||
|         return value | ||||
| def _get_env_value(env_var: str, default_value: str) -> str: | ||||
|     if env_var in os.environ: | ||||
|         return os.environ[env_var] | ||||
|     return default_value | ||||
|  | ||||
|  | ||||
| def _get_env_int_value(env_var: str, default_value: int) -> int: | ||||
|     value = _get_env_value(env_var, str(default_value)) | ||||
|     return int(value) | ||||
|  | ||||
|  | ||||
| def _get_env_float_value(env_var: str, default_value: float) -> float: | ||||
|     value = _get_env_value(env_var, str(default_value)) | ||||
|     return float(value) | ||||
|   | ||||
| @@ -1,30 +1,135 @@ | ||||
| """ | ||||
| Camera event loop | ||||
| """ | ||||
| import datetime | ||||
| import logging | ||||
| import typing | ||||
|  | ||||
| import cv2 | ||||
| import depthai as dai | ||||
| import numpy as np | ||||
| import paho.mqtt.client as mqtt | ||||
|  | ||||
| import events.events_pb2 | ||||
|  | ||||
| import depthai as dai | ||||
| import cv2 | ||||
| import numpy as np | ||||
|  | ||||
| logger = logging.getLogger(__name__) | ||||
|  | ||||
| NN_PATH = "/models/mobile_object_localizer_192x192_openvino_2021.4_6shave.blob" | ||||
| NN_WIDTH = 192 | ||||
| NN_HEIGHT = 192 | ||||
| _NN_PATH = "/models/mobile_object_localizer_192x192_openvino_2021.4_6shave.blob" | ||||
| _NN_WIDTH = 192 | ||||
| _NN_HEIGHT = 192 | ||||
|  | ||||
|  | ||||
| class FramePublisher: | ||||
|     def __init__(self, mqtt_client: mqtt.Client, frame_topic: str, objects_topic: str, objects_threshold: float, | ||||
|                  img_width: int, img_height: int): | ||||
| class ObjectProcessor: | ||||
|     """ | ||||
|     Processor for Object detection | ||||
|     """ | ||||
|  | ||||
|     def __init__(self, mqtt_client: mqtt.Client, objects_topic: str, objects_threshold: float): | ||||
|         self._mqtt_client = mqtt_client | ||||
|         self._frame_topic = frame_topic | ||||
|         self._objects_topic = objects_topic | ||||
|         self._objects_threshold = objects_threshold | ||||
|  | ||||
|     def process(self, in_nn: dai.NNData, frame_ref) -> None: | ||||
|         """ | ||||
|         Parse and publish result of NeuralNetwork result | ||||
|         :param in_nn: NeuralNetwork result read from device | ||||
|         :param frame_ref: Id of the frame where objects are been detected | ||||
|         :return: | ||||
|         """ | ||||
|         detection_boxes = np.array(in_nn.getLayerFp16("ExpandDims")).reshape((100, 4)) | ||||
|         detection_scores = np.array(in_nn.getLayerFp16("ExpandDims_2")).reshape((100,)) | ||||
|         # keep boxes bigger than threshold | ||||
|         mask = detection_scores >= self._objects_threshold | ||||
|         boxes = detection_boxes[mask] | ||||
|         scores = detection_scores[mask] | ||||
|  | ||||
|         if boxes.shape[0] > 0: | ||||
|             self._publish_objects(boxes, frame_ref, scores) | ||||
|  | ||||
|     def _publish_objects(self, boxes: np.array, frame_ref, scores: np.array) -> None: | ||||
|  | ||||
|         objects_msg = events.events_pb2.ObjectsMessage() | ||||
|         objs = [] | ||||
|         for i in range(boxes.shape[0]): | ||||
|             logger.debug("new object detected: %s", str(boxes[i])) | ||||
|             objs.append(_bbox_to_object(boxes[i], scores[i].astype(float))) | ||||
|         objects_msg.objects.extend(objs) | ||||
|         objects_msg.frame_ref.name = frame_ref.name | ||||
|         objects_msg.frame_ref.id = frame_ref.id | ||||
|         objects_msg.frame_ref.created_at.FromDatetime(frame_ref.created_at.ToDatetime()) | ||||
|         logger.debug("publish object event to %s", self._objects_topic) | ||||
|         self._mqtt_client.publish(topic=self._objects_topic, | ||||
|                                   payload=objects_msg.SerializeToString(), | ||||
|                                   qos=0, | ||||
|                                   retain=False) | ||||
|  | ||||
|  | ||||
| class FrameProcessError(Exception): | ||||
|     """ | ||||
|     Error base for invalid frame processing | ||||
|  | ||||
|     Attributes: | ||||
|         message -- explanation of the error | ||||
|     """ | ||||
|  | ||||
|     def __init__(self, message: str): | ||||
|         """ | ||||
|         :param message: explanation of the error | ||||
|         """ | ||||
|         self.message = message | ||||
|  | ||||
|  | ||||
| class FrameProcessor: | ||||
|     """ | ||||
|     Processor for camera frames | ||||
|     """ | ||||
|  | ||||
|     def __init__(self, mqtt_client: mqtt.Client, frame_topic: str): | ||||
|         self._mqtt_client = mqtt_client | ||||
|         self._frame_topic = frame_topic | ||||
|  | ||||
|     def process(self, img: dai.ImgFrame) -> typing.Any: | ||||
|         """ | ||||
|         Publish camera frames | ||||
|         :param img: | ||||
|         :return: | ||||
|             id frame reference | ||||
|         :raise: | ||||
|             FrameProcessError if frame can't be processed | ||||
|         """ | ||||
|         im_resize = img.getCvFrame() | ||||
|         is_success, im_buf_arr = cv2.imencode(".jpg", im_resize) | ||||
|         if not is_success: | ||||
|             raise FrameProcessError("unable to process to encode frame to jpg") | ||||
|         byte_im = im_buf_arr.tobytes() | ||||
|  | ||||
|         now = datetime.datetime.now() | ||||
|         frame_msg = events.events_pb2.FrameMessage() | ||||
|         frame_msg.id.name = "robocar-oak-camera-oak" | ||||
|         frame_msg.id.id = str(int(now.timestamp() * 1000)) | ||||
|         frame_msg.id.created_at.FromDatetime(now) | ||||
|         frame_msg.frame = byte_im | ||||
|         logger.debug("publish frame event to %s", self._frame_topic) | ||||
|         self._mqtt_client.publish(topic=self._frame_topic, | ||||
|                                   payload=frame_msg.SerializeToString(), | ||||
|                                   qos=0, | ||||
|                                   retain=False) | ||||
|         return frame_msg.id | ||||
|  | ||||
|  | ||||
| class PipelineController: | ||||
|     """ | ||||
|     Pipeline controller that drive camera device | ||||
|     """ | ||||
|  | ||||
|     def __init__(self, img_width: int, img_height: int, frame_processor: FrameProcessor, | ||||
|                  object_processor: ObjectProcessor): | ||||
|         self._img_width = img_width | ||||
|         self._img_height = img_height | ||||
|         self._pipeline = self._configure_pipeline() | ||||
|         self._frame_processor = frame_processor | ||||
|         self._object_processor = object_processor | ||||
|         self._stop = False | ||||
|  | ||||
|     def _configure_pipeline(self) -> dai.Pipeline: | ||||
|         logger.info("configure pipeline") | ||||
| @@ -32,20 +137,12 @@ class FramePublisher: | ||||
|  | ||||
|         pipeline.setOpenVINOVersion(version=dai.OpenVINO.VERSION_2021_4) | ||||
|  | ||||
|         # Define a neural network that will make predictions based on the source frames | ||||
|         detection_nn = pipeline.create(dai.node.NeuralNetwork) | ||||
|         detection_nn.setBlobPath(NN_PATH) | ||||
|         detection_nn.setNumPoolFrames(4) | ||||
|         detection_nn.input.setBlocking(False) | ||||
|         detection_nn.setNumInferenceThreads(2) | ||||
|  | ||||
|         xout_nn = pipeline.create(dai.node.XLinkOut) | ||||
|         xout_nn.setStreamName("nn") | ||||
|         xout_nn.input.setBlocking(False) | ||||
|         detection_nn = self._configure_detection_nn(pipeline) | ||||
|         xout_nn = self._configure_xout_nn(pipeline) | ||||
|  | ||||
|         # Resize image | ||||
|         manip = pipeline.create(dai.node.ImageManip) | ||||
|         manip.initialConfig.setResize(NN_WIDTH, NN_HEIGHT) | ||||
|         manip.initialConfig.setResize(_NN_WIDTH, _NN_HEIGHT) | ||||
|         manip.initialConfig.setFrameType(dai.ImgFrame.Type.RGB888p) | ||||
|         manip.initialConfig.setKeepAspectRatio(False) | ||||
|  | ||||
| @@ -53,7 +150,6 @@ class FramePublisher: | ||||
|         xout_rgb = pipeline.create(dai.node.XLinkOut) | ||||
|         xout_rgb.setStreamName("rgb") | ||||
|  | ||||
|  | ||||
|         # Properties | ||||
|         cam_rgb.setBoardSocket(dai.CameraBoardSocket.RGB) | ||||
|         cam_rgb.setPreviewSize(width=self._img_width, height=self._img_height) | ||||
| @@ -72,13 +168,33 @@ class FramePublisher: | ||||
|         logger.info("pipeline configured") | ||||
|         return pipeline | ||||
|  | ||||
|     def run(self): | ||||
|     @staticmethod | ||||
|     def _configure_xout_nn(pipeline: dai.Pipeline) -> dai.node.XLinkOut: | ||||
|         xout_nn = pipeline.create(dai.node.XLinkOut) | ||||
|         xout_nn.setStreamName("nn") | ||||
|         xout_nn.input.setBlocking(False) | ||||
|         return xout_nn | ||||
|  | ||||
|     @staticmethod | ||||
|     def _configure_detection_nn(pipeline: dai.Pipeline) -> dai.node.NeuralNetwork: | ||||
|         # Define a neural network that will make predictions based on the source frames | ||||
|         detection_nn = pipeline.create(dai.node.NeuralNetwork) | ||||
|         detection_nn.setBlobPath(_NN_PATH) | ||||
|         detection_nn.setNumPoolFrames(4) | ||||
|         detection_nn.input.setBlocking(False) | ||||
|         detection_nn.setNumInferenceThreads(2) | ||||
|         return detection_nn | ||||
|  | ||||
|     def run(self) -> None: | ||||
|         """ | ||||
|         Start event loop | ||||
|         :return: | ||||
|         """ | ||||
|         # Connect to device and start pipeline | ||||
|         with dai.Device(self._pipeline) as device: | ||||
|             logger.info('MxId: %s', device.getDeviceInfo().getMxId()) | ||||
|             logger.info('USB speed: %s', device.getUsbSpeed()) | ||||
|             logger.info('Connected cameras: %s', device.getConnectedCameras()) | ||||
|  | ||||
|             logger.info("output queues found: %s", device.getOutputQueueNames()) | ||||
|  | ||||
|             device.startPipeline() | ||||
| @@ -87,65 +203,44 @@ class FramePublisher: | ||||
|             q_rgb = device.getOutputQueue(name="rgb", maxSize=queue_size, blocking=False) | ||||
|             q_nn = device.getOutputQueue(name="nn", maxSize=queue_size, blocking=False) | ||||
|  | ||||
|             self._stop = False | ||||
|             while True: | ||||
|                 if self._stop: | ||||
|                     logger.info("stop loop event") | ||||
|                     return | ||||
|                 try: | ||||
|                     logger.debug("wait for new frame") | ||||
|                     inRgb = q_rgb.get()  # blocking call, will wait until a new data has arrived | ||||
|                     self._loop_on_camera_events(q_nn, q_rgb) | ||||
|                 # pylint: disable=broad-except # bad frame or event must not stop loop | ||||
|                 except Exception as ex: | ||||
|                     logger.exception("unexpected error: %s", str(ex)) | ||||
|  | ||||
|                     im_resize = inRgb.getCvFrame() | ||||
|     def _loop_on_camera_events(self, q_nn: dai.DataOutputQueue, q_rgb: dai.DataOutputQueue): | ||||
|         logger.debug("wait for new frame") | ||||
|  | ||||
|                     is_success, im_buf_arr = cv2.imencode(".jpg", im_resize) | ||||
|                     byte_im = im_buf_arr.tobytes() | ||||
|         # Wait for frame | ||||
|         in_rgb: dai.ImgFrame = q_rgb.get()  # blocking call, will wait until a new data has arrived | ||||
|         try: | ||||
|             frame_ref = self._frame_processor.process(in_rgb) | ||||
|         except FrameProcessError as ex: | ||||
|             logger.error("unable to process frame: %s", str(ex)) | ||||
|         # Read NN result | ||||
|         in_nn: dai.NNData = q_nn.get() | ||||
|         self._object_processor.process(in_nn, frame_ref) | ||||
|  | ||||
|                     now = datetime.datetime.now() | ||||
|                     frame_msg = events.events_pb2.FrameMessage() | ||||
|                     frame_msg.id.name = "robocar-oak-camera-oak" | ||||
|                     frame_msg.id.id = str(int(now.timestamp() * 1000)) | ||||
|                     frame_msg.id.created_at.FromDatetime(now) | ||||
|                     frame_msg.frame = byte_im | ||||
|     def stop(self): | ||||
|         """ | ||||
|         Stop event loop, if loop is not running, do nothing | ||||
|         :return: | ||||
|         """ | ||||
|         self._stop = True | ||||
|  | ||||
|                     logger.debug("publish frame event to %s", self._frame_topic) | ||||
|                     self._mqtt_client.publish(topic=self._frame_topic, | ||||
|                                               payload=frame_msg.SerializeToString(), | ||||
|                                               qos=0, | ||||
|                                               retain=False) | ||||
|  | ||||
|                     in_nn = q_nn.get() | ||||
|  | ||||
|                     # get outputs | ||||
|                     detection_boxes = np.array(in_nn.getLayerFp16("ExpandDims")).reshape((100, 4)) | ||||
|                     detection_scores = np.array(in_nn.getLayerFp16("ExpandDims_2")).reshape((100,)) | ||||
|  | ||||
|                     # keep boxes bigger than threshold | ||||
|                     mask = detection_scores >= self._objects_threshold | ||||
|                     boxes = detection_boxes[mask] | ||||
|                     scores = detection_scores[mask] | ||||
|  | ||||
|                     if boxes.shape[0] > 0: | ||||
|                         objects_msg = events.events_pb2.ObjectsMessage() | ||||
|                         objs = [] | ||||
|                         for i in range(boxes.shape[0]): | ||||
|                             bbox = boxes[i] | ||||
|                             logger.debug("new object detected: %s", str(bbox)) | ||||
|                             o = events.events_pb2.Object() | ||||
|                             o.type = events.events_pb2.TypeObject.ANY | ||||
|                             o.top = bbox[0].astype(float) | ||||
|                             o.right = bbox[3].astype(float) | ||||
|                             o.bottom = bbox[2].astype(float) | ||||
|                             o.left = bbox[1].astype(float) | ||||
|                             o.confidence = scores[i].astype(float) | ||||
|                             objs.append(o) | ||||
|                         objects_msg.objects.extend(objs) | ||||
|  | ||||
|                         objects_msg.frame_ref.name = frame_msg.id.name | ||||
|                         objects_msg.frame_ref.id = frame_msg.id.id | ||||
|                         objects_msg.frame_ref.created_at.FromDatetime(now) | ||||
|  | ||||
|                         logger.debug("publish object event to %s", self._frame_topic) | ||||
|                         self._mqtt_client.publish(topic=self._objects_topic, | ||||
|                                                   payload=objects_msg.SerializeToString(), | ||||
|                                                   qos=0, | ||||
|                                                   retain=False) | ||||
|  | ||||
|                 except Exception as e: | ||||
|                     logger.exception("unexpected error: %s", str(e)) | ||||
| def _bbox_to_object(bbox: np.array, score: float) -> events.events_pb2.Object: | ||||
|     obj = events.events_pb2.Object() | ||||
|     obj.type = events.events_pb2.TypeObject.ANY | ||||
|     obj.top = bbox[0].astype(float) | ||||
|     obj.right = bbox[3].astype(float) | ||||
|     obj.bottom = bbox[2].astype(float) | ||||
|     obj.left = bbox[1].astype(float) | ||||
|     obj.confidence = score | ||||
|     return obj | ||||
|   | ||||
							
								
								
									
										0
									
								
								camera/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								camera/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										150
									
								
								camera/tests/test_depthai.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								camera/tests/test_depthai.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,150 @@ | ||||
| import datetime | ||||
| import unittest.mock | ||||
|  | ||||
| import depthai as dai | ||||
| import numpy as np | ||||
| import paho.mqtt.client as mqtt | ||||
| import pytest | ||||
| import pytest_mock | ||||
|  | ||||
| import camera.depthai | ||||
| import events.events_pb2 | ||||
|  | ||||
| Object = dict[str, float] | ||||
|  | ||||
|  | ||||
| @pytest.fixture | ||||
| def mqtt_client(mocker: pytest_mock.MockerFixture) -> mqtt.Client: | ||||
|     return mocker.MagicMock() | ||||
|  | ||||
|  | ||||
| class TestObjectProcessor: | ||||
|     @pytest.fixture | ||||
|     def frame_ref(self): | ||||
|         now = datetime.datetime.now() | ||||
|         frame_msg = events.events_pb2.FrameMessage() | ||||
|         frame_msg.id.name = "robocar-oak-camera-oak" | ||||
|         frame_msg.id.id = str(int(now.timestamp() * 1000)) | ||||
|         frame_msg.id.created_at.FromDatetime(now) | ||||
|         return frame_msg.id | ||||
|  | ||||
|     @pytest.fixture | ||||
|     def object1(self) -> Object: | ||||
|         return { | ||||
|             "left": 0.3, | ||||
|             "right": 0.7, | ||||
|             "top": 0.1, | ||||
|             "bottom": 0.6, | ||||
|             "score": 0.8, | ||||
|         } | ||||
|  | ||||
|     @pytest.fixture | ||||
|     def raw_objects_empty(self, mocker: pytest_mock.MockerFixture) -> dai.NNData: | ||||
|         raw_objects = mocker.MagicMock() | ||||
|  | ||||
|         def mock_return(name): | ||||
|             if name == "ExpandDims": | ||||
|                 return [[0] * 4] * 100 | ||||
|             elif name == "ExpandDims_2": | ||||
|                 return [0] * 100 | ||||
|             else: | ||||
|                 raise ValueError(f"{name} is not a valid arg") | ||||
|  | ||||
|         m = mocker.patch(target='depthai.NNData.getLayerFp16', autospec=True) | ||||
|         m.getLayerFp16 = mock_return | ||||
|         return m | ||||
|  | ||||
|     @pytest.fixture | ||||
|     def raw_objects_one(self, mocker: pytest_mock.MockerFixture, object1: Object) -> dai.NNData: | ||||
|         def mock_return(name): | ||||
|             if name == "ExpandDims":  # Detection boxes | ||||
|                 boxes = [[0] * 4] * 100 | ||||
|                 boxes[0] = [object1["top"], object1["left"], object1["bottom"], object1["right"]] | ||||
|                 return np.array(boxes) | ||||
|  | ||||
|             elif name == "ExpandDims_2":  # Detection scores | ||||
|                 scores = [0] * 100 | ||||
|                 scores[0] = object1["score"] | ||||
|                 return scores | ||||
|             else: | ||||
|                 raise ValueError(f"{name} is not a valid arg") | ||||
|  | ||||
|         m = mocker.patch(target='depthai.NNData.getLayerFp16', autospec=True) | ||||
|         m.getLayerFp16 = mock_return | ||||
|         return m | ||||
|  | ||||
|     @pytest.fixture | ||||
|     def object_processor(self, mqtt_client: mqtt.Client) -> camera.depthai.ObjectProcessor: | ||||
|         return camera.depthai.ObjectProcessor(mqtt_client, "topic/object", 0.2) | ||||
|  | ||||
|     def test_process_without_object(self, object_processor: camera.depthai.ObjectProcessor, mqtt_client, | ||||
|                                     raw_objects_empty, frame_ref): | ||||
|         object_processor.process(raw_objects_empty, frame_ref) | ||||
|         mqtt_client.publish.assert_not_called() | ||||
|  | ||||
|     def test_process_with_object_with_low_score(self, object_processor: camera.depthai.ObjectProcessor, mqtt_client, | ||||
|                                                 raw_objects_one, frame_ref): | ||||
|         object_processor._objects_threshold = 0.9 | ||||
|         object_processor.process(raw_objects_one, frame_ref) | ||||
|         mqtt_client.publish.assert_not_called() | ||||
|  | ||||
|     def test_process_with_one_object(self, | ||||
|                                      object_processor: camera.depthai.ObjectProcessor, mqtt_client, | ||||
|                                      raw_objects_one, frame_ref, object1: Object): | ||||
|         object_processor.process(raw_objects_one, frame_ref) | ||||
|         left = object1["left"] | ||||
|         right = object1["right"] | ||||
|         top = object1["top"] | ||||
|         bottom = object1["bottom"] | ||||
|         score = object1["score"] | ||||
|  | ||||
|         pub_mock: unittest.mock.MagicMock = mqtt_client.publish | ||||
|         pub_mock.assert_called_once_with(payload=unittest.mock.ANY, qos=0, retain=False, topic="topic/object") | ||||
|         payload = pub_mock.call_args.kwargs['payload'] | ||||
|         objects_msg = events.events_pb2.ObjectsMessage() | ||||
|         objects_msg.ParseFromString(payload) | ||||
|         assert len(objects_msg.objects) == 1 | ||||
|         assert left - 0.0001 < objects_msg.objects[0].left < left + 0.0001 | ||||
|         assert right - 0.0001 < objects_msg.objects[0].right < right + 0.0001 | ||||
|         assert top - 0.0001 < objects_msg.objects[0].top < top + 0.0001 | ||||
|         assert bottom - 0.0001 < objects_msg.objects[0].bottom < bottom + 0.0001 | ||||
|         assert score - 0.0001 < objects_msg.objects[0].confidence < score + 0.0001 | ||||
|         assert objects_msg.frame_ref == frame_ref | ||||
|  | ||||
|  | ||||
| class TestFrameProcessor: | ||||
|     @pytest.fixture | ||||
|     def frame_processor(self, mqtt_client: mqtt.Client) -> camera.depthai.FrameProcessor: | ||||
|         return camera.depthai.FrameProcessor(mqtt_client, "topic/frame") | ||||
|  | ||||
|     def test_process(self, frame_processor: camera.depthai.FrameProcessor, mocker: pytest_mock.MockerFixture, | ||||
|                      mqtt_client: mqtt.Client): | ||||
|         img: dai.ImgFrame = mocker.MagicMock() | ||||
|         mocker.patch(target="cv2.imencode").return_value = (True, np.array(b"img content")) | ||||
|  | ||||
|         frame_ref = frame_processor.process(img) | ||||
|  | ||||
|         pub_mock: unittest.mock.MagicMock = mqtt_client.publish | ||||
|         pub_mock.assert_called_once_with(payload=unittest.mock.ANY, qos=0, retain=False, topic="topic/frame") | ||||
|         payload = pub_mock.call_args.kwargs['payload'] | ||||
|         frame_msg = events.events_pb2.FrameMessage() | ||||
|         frame_msg.ParseFromString(payload) | ||||
|  | ||||
|         assert frame_msg.id == frame_ref | ||||
|         assert frame_msg.frame == b"img content" | ||||
|  | ||||
|         assert frame_msg.id.name == "robocar-oak-camera-oak" | ||||
|         assert len(frame_msg.id.id) is 13 | ||||
|         now = datetime.datetime.now() | ||||
|         assert now - datetime.timedelta( | ||||
|             milliseconds=10) < frame_msg.id.created_at.ToDatetime() < now + datetime.timedelta(milliseconds=10) | ||||
|  | ||||
|     def test_process_error(self, frame_processor: camera.depthai.FrameProcessor, mocker: pytest_mock.MockerFixture, | ||||
|                            mqtt_client: mqtt.Client): | ||||
|         img: dai.ImgFrame = mocker.MagicMock() | ||||
|         mocker.patch(target="cv2.imencode").return_value = (False, None) | ||||
|  | ||||
|         with pytest.raises(camera.depthai.FrameProcessError) as ex: | ||||
|             _ = frame_processor.process(img) | ||||
|         exception_raised = ex.value | ||||
|         assert exception_raised.message == "unable to process to encode frame to jpg" | ||||
							
								
								
									
										839
									
								
								poetry.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										839
									
								
								poetry.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,839 @@ | ||||
| [[package]] | ||||
| name = "astroid" | ||||
| version = "2.12.12" | ||||
| description = "An abstract syntax tree for Python with inference support." | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.7.2" | ||||
|  | ||||
| [package.dependencies] | ||||
| lazy-object-proxy = ">=1.4.0" | ||||
| wrapt = [ | ||||
|     {version = ">=1.11,<2", markers = "python_version < \"3.11\""}, | ||||
|     {version = ">=1.14,<2", markers = "python_version >= \"3.11\""}, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "attrs" | ||||
| version = "22.1.0" | ||||
| description = "Classes Without Boilerplate" | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.5" | ||||
|  | ||||
| [package.extras] | ||||
| dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] | ||||
| docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] | ||||
| tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] | ||||
| tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] | ||||
|  | ||||
| [[package]] | ||||
| name = "beautifulsoup4" | ||||
| version = "4.11.1" | ||||
| description = "Screen-scraping library" | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = ">=3.6.0" | ||||
|  | ||||
| [package.dependencies] | ||||
| soupsieve = ">1.2" | ||||
|  | ||||
| [package.extras] | ||||
| html5lib = ["html5lib"] | ||||
| lxml = ["lxml"] | ||||
|  | ||||
| [[package]] | ||||
| name = "blobconverter" | ||||
| version = "1.3.0" | ||||
| description = "The tool that allows you to convert neural networks to MyriadX blob" | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = "*" | ||||
|  | ||||
| [package.dependencies] | ||||
| boto3 = "*" | ||||
| PyYAML = "*" | ||||
| requests = "*" | ||||
|  | ||||
| [[package]] | ||||
| name = "boto3" | ||||
| version = "1.24.94" | ||||
| description = "The AWS SDK for Python" | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = ">= 3.7" | ||||
|  | ||||
| [package.dependencies] | ||||
| botocore = ">=1.27.94,<1.28.0" | ||||
| jmespath = ">=0.7.1,<2.0.0" | ||||
| s3transfer = ">=0.6.0,<0.7.0" | ||||
|  | ||||
| [package.extras] | ||||
| crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] | ||||
|  | ||||
| [[package]] | ||||
| name = "botocore" | ||||
| version = "1.27.94" | ||||
| description = "Low-level, data-driven core of boto 3." | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = ">= 3.7" | ||||
|  | ||||
| [package.dependencies] | ||||
| jmespath = ">=0.7.1,<2.0.0" | ||||
| python-dateutil = ">=2.1,<3.0.0" | ||||
| urllib3 = ">=1.25.4,<1.27" | ||||
|  | ||||
| [package.extras] | ||||
| crt = ["awscrt (==0.14.0)"] | ||||
|  | ||||
| [[package]] | ||||
| name = "certifi" | ||||
| version = "2022.9.24" | ||||
| description = "Python package for providing Mozilla's CA Bundle." | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = ">=3.6" | ||||
|  | ||||
| [[package]] | ||||
| name = "charset-normalizer" | ||||
| version = "2.1.1" | ||||
| description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = ">=3.6.0" | ||||
|  | ||||
| [package.extras] | ||||
| unicode-backport = ["unicodedata2"] | ||||
|  | ||||
| [[package]] | ||||
| name = "colorama" | ||||
| version = "0.4.5" | ||||
| description = "Cross-platform colored terminal text." | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" | ||||
|  | ||||
| [[package]] | ||||
| name = "depthai" | ||||
| version = "2.17.4.0" | ||||
| description = "DepthAI Python Library" | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = ">=3.6" | ||||
|  | ||||
| [[package]] | ||||
| name = "dill" | ||||
| version = "0.3.5.1" | ||||
| description = "serialize all of python" | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" | ||||
|  | ||||
| [package.extras] | ||||
| graph = ["objgraph (>=1.7.2)"] | ||||
|  | ||||
| [[package]] | ||||
| name = "google" | ||||
| version = "3.0.0" | ||||
| description = "Python bindings to the Google search engine." | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = "*" | ||||
|  | ||||
| [package.dependencies] | ||||
| beautifulsoup4 = "*" | ||||
|  | ||||
| [[package]] | ||||
| name = "idna" | ||||
| version = "3.4" | ||||
| description = "Internationalized Domain Names in Applications (IDNA)" | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = ">=3.5" | ||||
|  | ||||
| [[package]] | ||||
| name = "iniconfig" | ||||
| version = "1.1.1" | ||||
| description = "iniconfig: brain-dead simple config-ini parsing" | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = "*" | ||||
|  | ||||
| [[package]] | ||||
| name = "isort" | ||||
| version = "5.10.1" | ||||
| description = "A Python utility / library to sort Python imports." | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.6.1,<4.0" | ||||
|  | ||||
| [package.extras] | ||||
| colors = ["colorama (>=0.4.3,<0.5.0)"] | ||||
| pipfile-deprecated-finder = ["pipreqs", "requirementslib"] | ||||
| plugins = ["setuptools"] | ||||
| requirements-deprecated-finder = ["pip-api", "pipreqs"] | ||||
|  | ||||
| [[package]] | ||||
| name = "jmespath" | ||||
| version = "1.0.1" | ||||
| description = "JSON Matching Expressions" | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = ">=3.7" | ||||
|  | ||||
| [[package]] | ||||
| name = "lazy-object-proxy" | ||||
| version = "1.7.1" | ||||
| description = "A fast and thorough lazy object proxy." | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.6" | ||||
|  | ||||
| [[package]] | ||||
| name = "mccabe" | ||||
| version = "0.7.0" | ||||
| description = "McCabe checker, plugin for flake8" | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.6" | ||||
|  | ||||
| [[package]] | ||||
| name = "numpy" | ||||
| version = "1.23.4" | ||||
| description = "NumPy is the fundamental package for array computing with Python." | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = ">=3.8" | ||||
|  | ||||
| [[package]] | ||||
| name = "opencv-python" | ||||
| version = "4.6.0.66" | ||||
| description = "Wrapper package for OpenCV python bindings." | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = ">=3.6" | ||||
|  | ||||
| [package.dependencies] | ||||
| numpy = [ | ||||
|     {version = ">=1.21.2", markers = "python_version >= \"3.10\" or python_version >= \"3.6\" and platform_system == \"Darwin\" and platform_machine == \"arm64\""}, | ||||
|     {version = ">=1.19.3", markers = "python_version >= \"3.6\" and platform_system == \"Linux\" and platform_machine == \"aarch64\" or python_version >= \"3.9\""}, | ||||
|     {version = ">=1.14.5", markers = "python_version >= \"3.7\""}, | ||||
|     {version = ">=1.17.3", markers = "python_version >= \"3.8\""}, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "packaging" | ||||
| version = "21.3" | ||||
| description = "Core utilities for Python packages" | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.6" | ||||
|  | ||||
| [package.dependencies] | ||||
| pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" | ||||
|  | ||||
| [[package]] | ||||
| name = "paho-mqtt" | ||||
| version = "1.6.1" | ||||
| description = "MQTT version 5.0/3.1.1 client class" | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = "*" | ||||
|  | ||||
| [package.extras] | ||||
| proxy = ["PySocks"] | ||||
|  | ||||
| [[package]] | ||||
| name = "platformdirs" | ||||
| version = "2.5.2" | ||||
| description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.7" | ||||
|  | ||||
| [package.extras] | ||||
| docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx (>=4)", "sphinx-autodoc-typehints (>=1.12)"] | ||||
| test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] | ||||
|  | ||||
| [[package]] | ||||
| name = "pluggy" | ||||
| version = "1.0.0" | ||||
| description = "plugin and hook calling mechanisms for python" | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.6" | ||||
|  | ||||
| [package.extras] | ||||
| dev = ["pre-commit", "tox"] | ||||
| testing = ["pytest", "pytest-benchmark"] | ||||
|  | ||||
| [[package]] | ||||
| name = "protobuf" | ||||
| version = "4.21.8" | ||||
| description = "" | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = ">=3.7" | ||||
|  | ||||
| [[package]] | ||||
| name = "protobuf3" | ||||
| version = "0.2.1" | ||||
| description = "Protocol buffers library for Python 3" | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = "*" | ||||
|  | ||||
| [[package]] | ||||
| name = "py" | ||||
| version = "1.11.0" | ||||
| description = "library with cross-python path, ini-parsing, io, code, log facilities" | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" | ||||
|  | ||||
| [[package]] | ||||
| name = "pylint" | ||||
| version = "2.15.4" | ||||
| description = "python code static checker" | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.7.2" | ||||
|  | ||||
| [package.dependencies] | ||||
| astroid = ">=2.12.11,<=2.14.0-dev0" | ||||
| colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} | ||||
| dill = ">=0.2" | ||||
| isort = ">=4.2.5,<6" | ||||
| mccabe = ">=0.6,<0.8" | ||||
| platformdirs = ">=2.2.0" | ||||
| tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} | ||||
| tomlkit = ">=0.10.1" | ||||
|  | ||||
| [package.extras] | ||||
| spelling = ["pyenchant (>=3.2,<4.0)"] | ||||
| testutils = ["gitpython (>3)"] | ||||
|  | ||||
| [[package]] | ||||
| name = "pyparsing" | ||||
| version = "3.0.9" | ||||
| description = "pyparsing module - Classes and methods to define and execute parsing grammars" | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.6.8" | ||||
|  | ||||
| [package.extras] | ||||
| diagrams = ["jinja2", "railroad-diagrams"] | ||||
|  | ||||
| [[package]] | ||||
| name = "pytest" | ||||
| version = "7.1.3" | ||||
| description = "pytest: simple powerful testing with Python" | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.7" | ||||
|  | ||||
| [package.dependencies] | ||||
| attrs = ">=19.2.0" | ||||
| colorama = {version = "*", markers = "sys_platform == \"win32\""} | ||||
| iniconfig = "*" | ||||
| packaging = "*" | ||||
| pluggy = ">=0.12,<2.0" | ||||
| py = ">=1.8.2" | ||||
| tomli = ">=1.0.0" | ||||
|  | ||||
| [package.extras] | ||||
| testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] | ||||
|  | ||||
| [[package]] | ||||
| name = "pytest-mock" | ||||
| version = "3.10.0" | ||||
| description = "Thin-wrapper around the mock package for easier use with pytest" | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.7" | ||||
|  | ||||
| [package.dependencies] | ||||
| pytest = ">=5.0" | ||||
|  | ||||
| [package.extras] | ||||
| dev = ["pre-commit", "pytest-asyncio", "tox"] | ||||
|  | ||||
| [[package]] | ||||
| name = "python-dateutil" | ||||
| version = "2.8.2" | ||||
| description = "Extensions to the standard Python datetime module" | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" | ||||
|  | ||||
| [package.dependencies] | ||||
| six = ">=1.5" | ||||
|  | ||||
| [[package]] | ||||
| name = "pyyaml" | ||||
| version = "6.0" | ||||
| description = "YAML parser and emitter for Python" | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = ">=3.6" | ||||
|  | ||||
| [[package]] | ||||
| name = "requests" | ||||
| version = "2.28.1" | ||||
| description = "Python HTTP for Humans." | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = ">=3.7, <4" | ||||
|  | ||||
| [package.dependencies] | ||||
| certifi = ">=2017.4.17" | ||||
| charset-normalizer = ">=2,<3" | ||||
| idna = ">=2.5,<4" | ||||
| urllib3 = ">=1.21.1,<1.27" | ||||
|  | ||||
| [package.extras] | ||||
| socks = ["PySocks (>=1.5.6,!=1.5.7)"] | ||||
| use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] | ||||
|  | ||||
| [[package]] | ||||
| name = "s3transfer" | ||||
| version = "0.6.0" | ||||
| description = "An Amazon S3 Transfer Manager" | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = ">= 3.7" | ||||
|  | ||||
| [package.dependencies] | ||||
| botocore = ">=1.12.36,<2.0a.0" | ||||
|  | ||||
| [package.extras] | ||||
| crt = ["botocore[crt] (>=1.20.29,<2.0a.0)"] | ||||
|  | ||||
| [[package]] | ||||
| name = "six" | ||||
| version = "1.16.0" | ||||
| description = "Python 2 and 3 compatibility utilities" | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" | ||||
|  | ||||
| [[package]] | ||||
| name = "soupsieve" | ||||
| version = "2.3.2.post1" | ||||
| description = "A modern CSS selector implementation for Beautiful Soup." | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = ">=3.6" | ||||
|  | ||||
| [[package]] | ||||
| name = "tomli" | ||||
| version = "2.0.1" | ||||
| description = "A lil' TOML parser" | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.7" | ||||
|  | ||||
| [[package]] | ||||
| name = "tomlkit" | ||||
| version = "0.11.5" | ||||
| description = "Style preserving TOML library" | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.6,<4.0" | ||||
|  | ||||
| [[package]] | ||||
| name = "urllib3" | ||||
| version = "1.26.12" | ||||
| description = "HTTP library with thread-safe connection pooling, file post, and more." | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4" | ||||
|  | ||||
| [package.extras] | ||||
| brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] | ||||
| secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] | ||||
| socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] | ||||
|  | ||||
| [[package]] | ||||
| name = "wrapt" | ||||
| version = "1.14.1" | ||||
| description = "Module for decorators, wrappers and monkey patching." | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" | ||||
|  | ||||
| [metadata] | ||||
| lock-version = "1.1" | ||||
| python-versions = "^3.10" | ||||
| content-hash = "d062fb11b00c63a20b69560322be0723850a7fe3a4363bfe0339f1f75ffd0e2e" | ||||
|  | ||||
| [metadata.files] | ||||
| astroid = [ | ||||
|     {file = "astroid-2.12.12-py3-none-any.whl", hash = "sha256:72702205200b2a638358369d90c222d74ebc376787af8fb2f7f2a86f7b5cc85f"}, | ||||
|     {file = "astroid-2.12.12.tar.gz", hash = "sha256:1c00a14f5a3ed0339d38d2e2e5b74ea2591df5861c0936bb292b84ccf3a78d83"}, | ||||
| ] | ||||
| attrs = [ | ||||
|     {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, | ||||
|     {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, | ||||
| ] | ||||
| beautifulsoup4 = [ | ||||
|     {file = "beautifulsoup4-4.11.1-py3-none-any.whl", hash = "sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30"}, | ||||
|     {file = "beautifulsoup4-4.11.1.tar.gz", hash = "sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693"}, | ||||
| ] | ||||
| blobconverter = [ | ||||
|     {file = "blobconverter-1.3.0-py3-none-any.whl", hash = "sha256:7dc96c94ea4d609cd2421b5aa3f31f164b51cfa9cfd3747f9e6e3997f6d27cab"}, | ||||
|     {file = "blobconverter-1.3.0.tar.gz", hash = "sha256:6f1a2cc6a4d0347a675eddc217aa0751bd5bac09fd6b19195b641f6ea9eb1cc1"}, | ||||
| ] | ||||
| boto3 = [ | ||||
|     {file = "boto3-1.24.94-py3-none-any.whl", hash = "sha256:f13db0beb3c9fe2cc1ed0f031189f144610d2909b5874a616e77b0bd1ae3b686"}, | ||||
|     {file = "boto3-1.24.94.tar.gz", hash = "sha256:f4842b395d1580454756622069f4ca0408993885ecede967001d2c101201cdfa"}, | ||||
| ] | ||||
| botocore = [ | ||||
|     {file = "botocore-1.27.94-py3-none-any.whl", hash = "sha256:8237c070d2ab29fac4fbcfe9dd2e84e0ee147402e0fed3ac1629f92459c7f1d2"}, | ||||
|     {file = "botocore-1.27.94.tar.gz", hash = "sha256:572224608a0b7662966fc303b768e2eba61bf53bdbf314481cd9e63a0d8e1a66"}, | ||||
| ] | ||||
| certifi = [ | ||||
|     {file = "certifi-2022.9.24-py3-none-any.whl", hash = "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382"}, | ||||
|     {file = "certifi-2022.9.24.tar.gz", hash = "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14"}, | ||||
| ] | ||||
| charset-normalizer = [ | ||||
|     {file = "charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"}, | ||||
|     {file = "charset_normalizer-2.1.1-py3-none-any.whl", hash = "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"}, | ||||
| ] | ||||
| colorama = [ | ||||
|     {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, | ||||
|     {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, | ||||
| ] | ||||
| depthai = [ | ||||
|     {file = "depthai-2.17.4.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:b482cf5a2bc378b4f9e39dc1fecae8c1b731aae014c6722452e9740e9acdafb5"}, | ||||
|     {file = "depthai-2.17.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bbeb827ca450e01e18edabad3e66a18d54e431955badefb98c31ad398effb95f"}, | ||||
|     {file = "depthai-2.17.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3aaac971ef52b32f004ecab595426b9d6d16dc59d83f5ee6d989dff2dc1e6e68"}, | ||||
|     {file = "depthai-2.17.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02ed24cc624f6e8d4a6e878fbab847f2d9acab48aeb1b17abda649fb538eed30"}, | ||||
|     {file = "depthai-2.17.4.0-cp310-cp310-win32.whl", hash = "sha256:2975cf96f46f9903bbe3355b7df2c6c3b4a9005250088065848d9c6a263ef19f"}, | ||||
|     {file = "depthai-2.17.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:be2b99b002c5e9bb63dd79edb51974436d8f9a942632d2b81146faa9613137d6"}, | ||||
|     {file = "depthai-2.17.4.0-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:ca5876c9fd13a07685922e349d76161ba914e07c6fd9153b50198a32f3b3a485"}, | ||||
|     {file = "depthai-2.17.4.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca9a6df834e49e600d4359c153c6aa2c1d3cbb2a0f9ebca6c1b746e048492e4e"}, | ||||
|     {file = "depthai-2.17.4.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cca0c20f29f88a0872de4bc1f9039c5deb2cefd43227c43b191ec3c99f0da7e"}, | ||||
|     {file = "depthai-2.17.4.0-cp36-cp36m-win32.whl", hash = "sha256:abddb6db252f6afcdda6c59c60263e495ada99474e820cb6313ef16bbcbe81b6"}, | ||||
|     {file = "depthai-2.17.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:e7245ceab5e9a5bde237b72acd3a6f701899e977670bda3c5186aa94e6f1823c"}, | ||||
|     {file = "depthai-2.17.4.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:cacbcb96c25815020692027324e594a95713e021731cfa031613da57b020d619"}, | ||||
|     {file = "depthai-2.17.4.0-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:b5868196838b603260b5c8533447ae6f24e2d89958e5297356fc98328b66c215"}, | ||||
|     {file = "depthai-2.17.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78f9fe96e769123797dd5f06cf0ec74021352bee4dd59f74c76bb9c57a6db18a"}, | ||||
|     {file = "depthai-2.17.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a730a3530f35b216f7efbdbad9343d3427024f69093a95ec5848a505f6f4e23"}, | ||||
|     {file = "depthai-2.17.4.0-cp37-cp37m-win32.whl", hash = "sha256:e90e10678b2d70d543873fce39e24bb1e18adf2ce9b877a840c3c69fd2009d69"}, | ||||
|     {file = "depthai-2.17.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:1515f9d1c3c1078e7cf95b87c9e4e24d03a5ba36f4c0a14704d816d4a378ead4"}, | ||||
|     {file = "depthai-2.17.4.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:92e71a879a9861bc28feb7d729d59746d0c202563c4b27831d30e0bd736caf6d"}, | ||||
|     {file = "depthai-2.17.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4628e27bc70a2f0e229abb1d68489c5b567b2c0bb477d60214a6491c24f37dad"}, | ||||
|     {file = "depthai-2.17.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ecf3d6f39313a8e34a370979b7272fe476b75d6c1fb129cf77d88d81e8b1112"}, | ||||
|     {file = "depthai-2.17.4.0-cp38-cp38-win32.whl", hash = "sha256:e510f7562a17db7b847b0b96b497db885a134d94263f5b6d9696fb1806518fd6"}, | ||||
|     {file = "depthai-2.17.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:227150025f2dac183dd4ed8052b923b8904cca42cac387de61f5a6d317e630af"}, | ||||
|     {file = "depthai-2.17.4.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:47b2585f088f5473469b0a67bac50863128ca70407b57fbbbdf152a6cbe2f920"}, | ||||
|     {file = "depthai-2.17.4.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:36728e5db17b0d9d1924387a11015fcb32e0edd35597991dc048870a46611c8e"}, | ||||
|     {file = "depthai-2.17.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2fad8a0b7ff938926bbd30fbb8c273e2b6d0a84c2e83405178d9c70138899c8b"}, | ||||
|     {file = "depthai-2.17.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20c1502ae539db6f5599af2a7bdf94dc55e866aa98c8146ec497f469791b4801"}, | ||||
|     {file = "depthai-2.17.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c81ff583e4d0c1e19914df6c9f83c3e742afbbb97b0cdca926b7e04f019996d"}, | ||||
|     {file = "depthai-2.17.4.0-cp39-cp39-win32.whl", hash = "sha256:700638ad886fa03b4d2e3a8d76e1c19b9ebcc4a08f4202100670f7ac7de6f7a9"}, | ||||
|     {file = "depthai-2.17.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:de7b5e4a15b0a9e15fdf19c5388e6aa9629ecc25a955675d400173f9a2dd199b"}, | ||||
|     {file = "depthai-2.17.4.0.tar.gz", hash = "sha256:b8e3c2eaa643c64e737435adaa23d54e3fda58baad1477f5176908689473a85f"}, | ||||
| ] | ||||
| dill = [ | ||||
|     {file = "dill-0.3.5.1-py2.py3-none-any.whl", hash = "sha256:33501d03270bbe410c72639b350e941882a8b0fd55357580fbc873fba0c59302"}, | ||||
|     {file = "dill-0.3.5.1.tar.gz", hash = "sha256:d75e41f3eff1eee599d738e76ba8f4ad98ea229db8b085318aa2b3333a208c86"}, | ||||
| ] | ||||
| google = [ | ||||
|     {file = "google-3.0.0-py2.py3-none-any.whl", hash = "sha256:889cf695f84e4ae2c55fbc0cfdaf4c1e729417fa52ab1db0485202ba173e4935"}, | ||||
|     {file = "google-3.0.0.tar.gz", hash = "sha256:143530122ee5130509ad5e989f0512f7cb218b2d4eddbafbad40fd10e8d8ccbe"}, | ||||
| ] | ||||
| idna = [ | ||||
|     {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, | ||||
|     {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, | ||||
| ] | ||||
| iniconfig = [ | ||||
|     {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, | ||||
|     {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, | ||||
| ] | ||||
| isort = [ | ||||
|     {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, | ||||
|     {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, | ||||
| ] | ||||
| jmespath = [ | ||||
|     {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, | ||||
|     {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, | ||||
| ] | ||||
| lazy-object-proxy = [ | ||||
|     {file = "lazy-object-proxy-1.7.1.tar.gz", hash = "sha256:d609c75b986def706743cdebe5e47553f4a5a1da9c5ff66d76013ef396b5a8a4"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bb8c5fd1684d60a9902c60ebe276da1f2281a318ca16c1d0a96db28f62e9166b"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a57d51ed2997e97f3b8e3500c984db50a554bb5db56c50b5dab1b41339b37e36"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd45683c3caddf83abbb1249b653a266e7069a09f486daa8863fb0e7496a9fdb"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8561da8b3dd22d696244d6d0d5330618c993a215070f473b699e00cf1f3f6443"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fccdf7c2c5821a8cbd0a9440a456f5050492f2270bd54e94360cac663398739b"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp310-cp310-win32.whl", hash = "sha256:898322f8d078f2654d275124a8dd19b079080ae977033b713f677afcfc88e2b9"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:85b232e791f2229a4f55840ed54706110c80c0a210d076eee093f2b2e33e1bfd"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:46ff647e76f106bb444b4533bb4153c7370cdf52efc62ccfc1a28bdb3cc95442"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12f3bb77efe1367b2515f8cb4790a11cffae889148ad33adad07b9b55e0ab22c"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c19814163728941bb871240d45c4c30d33b8a2e85972c44d4e63dd7107faba44"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:e40f2013d96d30217a51eeb1db28c9ac41e9d0ee915ef9d00da639c5b63f01a1"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:2052837718516a94940867e16b1bb10edb069ab475c3ad84fd1e1a6dd2c0fcfc"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp36-cp36m-win32.whl", hash = "sha256:6a24357267aa976abab660b1d47a34aaf07259a0c3859a34e536f1ee6e76b5bb"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp36-cp36m-win_amd64.whl", hash = "sha256:6aff3fe5de0831867092e017cf67e2750c6a1c7d88d84d2481bd84a2e019ec35"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6a6e94c7b02641d1311228a102607ecd576f70734dc3d5e22610111aeacba8a0"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ce15276a1a14549d7e81c243b887293904ad2d94ad767f42df91e75fd7b5b6"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e368b7f7eac182a59ff1f81d5f3802161932a41dc1b1cc45c1f757dc876b5d2c"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6ecbb350991d6434e1388bee761ece3260e5228952b1f0c46ffc800eb313ff42"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:553b0f0d8dbf21890dd66edd771f9b1b5f51bd912fa5f26de4449bfc5af5e029"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp37-cp37m-win32.whl", hash = "sha256:c7a683c37a8a24f6428c28c561c80d5f4fd316ddcf0c7cab999b15ab3f5c5c69"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp37-cp37m-win_amd64.whl", hash = "sha256:df2631f9d67259dc9620d831384ed7732a198eb434eadf69aea95ad18c587a28"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:07fa44286cda977bd4803b656ffc1c9b7e3bc7dff7d34263446aec8f8c96f88a"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dca6244e4121c74cc20542c2ca39e5c4a5027c81d112bfb893cf0790f96f57e"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91ba172fc5b03978764d1df5144b4ba4ab13290d7bab7a50f12d8117f8630c38"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:043651b6cb706eee4f91854da4a089816a6606c1428fd391573ef8cb642ae4f7"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b9e89b87c707dd769c4ea91f7a31538888aad05c116a59820f28d59b3ebfe25a"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp38-cp38-win32.whl", hash = "sha256:9d166602b525bf54ac994cf833c385bfcc341b364e3ee71e3bf5a1336e677b55"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:8f3953eb575b45480db6568306893f0bd9d8dfeeebd46812aa09ca9579595148"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dd7ed7429dbb6c494aa9bc4e09d94b778a3579be699f9d67da7e6804c422d3de"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70ed0c2b380eb6248abdef3cd425fc52f0abd92d2b07ce26359fcbc399f636ad"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7096a5e0c1115ec82641afbdd70451a144558ea5cf564a896294e346eb611be1"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f769457a639403073968d118bc70110e7dce294688009f5c24ab78800ae56dc8"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:39b0e26725c5023757fc1ab2a89ef9d7ab23b84f9251e28f9cc114d5b59c1b09"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp39-cp39-win32.whl", hash = "sha256:2130db8ed69a48a3440103d4a520b89d8a9405f1b06e2cc81640509e8bf6548f"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:677ea950bef409b47e51e733283544ac3d660b709cfce7b187f5ace137960d61"}, | ||||
|     {file = "lazy_object_proxy-1.7.1-pp37.pp38-none-any.whl", hash = "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84"}, | ||||
| ] | ||||
| mccabe = [ | ||||
|     {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, | ||||
|     {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, | ||||
| ] | ||||
| numpy = [ | ||||
|     {file = "numpy-1.23.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:95d79ada05005f6f4f337d3bb9de8a7774f259341c70bc88047a1f7b96a4bcb2"}, | ||||
|     {file = "numpy-1.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:926db372bc4ac1edf81cfb6c59e2a881606b409ddc0d0920b988174b2e2a767f"}, | ||||
|     {file = "numpy-1.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c237129f0e732885c9a6076a537e974160482eab8f10db6292e92154d4c67d71"}, | ||||
|     {file = "numpy-1.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8365b942f9c1a7d0f0dc974747d99dd0a0cdfc5949a33119caf05cb314682d3"}, | ||||
|     {file = "numpy-1.23.4-cp310-cp310-win32.whl", hash = "sha256:2341f4ab6dba0834b685cce16dad5f9b6606ea8a00e6da154f5dbded70fdc4dd"}, | ||||
|     {file = "numpy-1.23.4-cp310-cp310-win_amd64.whl", hash = "sha256:d331afac87c92373826af83d2b2b435f57b17a5c74e6268b79355b970626e329"}, | ||||
|     {file = "numpy-1.23.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:488a66cb667359534bc70028d653ba1cf307bae88eab5929cd707c761ff037db"}, | ||||
|     {file = "numpy-1.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ce03305dd694c4873b9429274fd41fc7eb4e0e4dea07e0af97a933b079a5814f"}, | ||||
|     {file = "numpy-1.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8981d9b5619569899666170c7c9748920f4a5005bf79c72c07d08c8a035757b0"}, | ||||
|     {file = "numpy-1.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a70a7d3ce4c0e9284e92285cba91a4a3f5214d87ee0e95928f3614a256a1488"}, | ||||
|     {file = "numpy-1.23.4-cp311-cp311-win32.whl", hash = "sha256:5e13030f8793e9ee42f9c7d5777465a560eb78fa7e11b1c053427f2ccab90c79"}, | ||||
|     {file = "numpy-1.23.4-cp311-cp311-win_amd64.whl", hash = "sha256:7607b598217745cc40f751da38ffd03512d33ec06f3523fb0b5f82e09f6f676d"}, | ||||
|     {file = "numpy-1.23.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7ab46e4e7ec63c8a5e6dbf5c1b9e1c92ba23a7ebecc86c336cb7bf3bd2fb10e5"}, | ||||
|     {file = "numpy-1.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8aae2fb3180940011b4862b2dd3756616841c53db9734b27bb93813cd79fce6"}, | ||||
|     {file = "numpy-1.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c053d7557a8f022ec823196d242464b6955a7e7e5015b719e76003f63f82d0f"}, | ||||
|     {file = "numpy-1.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0882323e0ca4245eb0a3d0a74f88ce581cc33aedcfa396e415e5bba7bf05f68"}, | ||||
|     {file = "numpy-1.23.4-cp38-cp38-win32.whl", hash = "sha256:dada341ebb79619fe00a291185bba370c9803b1e1d7051610e01ed809ef3a4ba"}, | ||||
|     {file = "numpy-1.23.4-cp38-cp38-win_amd64.whl", hash = "sha256:0fe563fc8ed9dc4474cbf70742673fc4391d70f4363f917599a7fa99f042d5a8"}, | ||||
|     {file = "numpy-1.23.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c67b833dbccefe97cdd3f52798d430b9d3430396af7cdb2a0c32954c3ef73894"}, | ||||
|     {file = "numpy-1.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f76025acc8e2114bb664294a07ede0727aa75d63a06d2fae96bf29a81747e4a7"}, | ||||
|     {file = "numpy-1.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12ac457b63ec8ded85d85c1e17d85efd3c2b0967ca39560b307a35a6703a4735"}, | ||||
|     {file = "numpy-1.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95de7dc7dc47a312f6feddd3da2500826defdccbc41608d0031276a24181a2c0"}, | ||||
|     {file = "numpy-1.23.4-cp39-cp39-win32.whl", hash = "sha256:f2f390aa4da44454db40a1f0201401f9036e8d578a25f01a6e237cea238337ef"}, | ||||
|     {file = "numpy-1.23.4-cp39-cp39-win_amd64.whl", hash = "sha256:f260da502d7441a45695199b4e7fd8ca87db659ba1c78f2bbf31f934fe76ae0e"}, | ||||
|     {file = "numpy-1.23.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:61be02e3bf810b60ab74e81d6d0d36246dbfb644a462458bb53b595791251911"}, | ||||
|     {file = "numpy-1.23.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:296d17aed51161dbad3c67ed6d164e51fcd18dbcd5dd4f9d0a9c6055dce30810"}, | ||||
|     {file = "numpy-1.23.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4d52914c88b4930dafb6c48ba5115a96cbab40f45740239d9f4159c4ba779962"}, | ||||
|     {file = "numpy-1.23.4.tar.gz", hash = "sha256:ed2cc92af0efad20198638c69bb0fc2870a58dabfba6eb722c933b48556c686c"}, | ||||
| ] | ||||
| opencv-python = [ | ||||
|     {file = "opencv-python-4.6.0.66.tar.gz", hash = "sha256:c5bfae41ad4031e66bb10ec4a0a2ffd3e514d092652781e8b1ac98d1b59f1158"}, | ||||
|     {file = "opencv_python-4.6.0.66-cp36-abi3-macosx_10_15_x86_64.whl", hash = "sha256:e6e448b62afc95c5b58f97e87ef84699e6607fe5c58730a03301c52496005cae"}, | ||||
|     {file = "opencv_python-4.6.0.66-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5af8ba35a4fcb8913ffb86e92403e9a656a4bff4a645d196987468f0f8947875"}, | ||||
|     {file = "opencv_python-4.6.0.66-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbdc84a9b4ea2cbae33861652d25093944b9959279200b7ae0badd32439f74de"}, | ||||
|     {file = "opencv_python-4.6.0.66-cp36-abi3-win32.whl", hash = "sha256:f482e78de6e7b0b060ff994ffd859bddc3f7f382bb2019ef157b0ea8ca8712f5"}, | ||||
|     {file = "opencv_python-4.6.0.66-cp36-abi3-win_amd64.whl", hash = "sha256:0dc82a3d8630c099d2f3ac1b1aabee164e8188db54a786abb7a4e27eba309440"}, | ||||
|     {file = "opencv_python-4.6.0.66-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:6e32af22e3202748bd233ed8f538741876191863882eba44e332d1a34993165b"}, | ||||
| ] | ||||
| packaging = [ | ||||
|     {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, | ||||
|     {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, | ||||
| ] | ||||
| paho-mqtt = [ | ||||
|     {file = "paho-mqtt-1.6.1.tar.gz", hash = "sha256:2a8291c81623aec00372b5a85558a372c747cbca8e9934dfe218638b8eefc26f"}, | ||||
| ] | ||||
| platformdirs = [ | ||||
|     {file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"}, | ||||
|     {file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"}, | ||||
| ] | ||||
| pluggy = [ | ||||
|     {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, | ||||
|     {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, | ||||
| ] | ||||
| protobuf = [ | ||||
|     {file = "protobuf-4.21.8-cp310-abi3-win32.whl", hash = "sha256:c252c55ee15175aa1b21b7b9896e6add5162d066d5202e75c39f96136f08cce3"}, | ||||
|     {file = "protobuf-4.21.8-cp310-abi3-win_amd64.whl", hash = "sha256:809ca0b225d3df42655a12f311dd0f4148a943c51f1ad63c38343e457492b689"}, | ||||
|     {file = "protobuf-4.21.8-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bbececaf3cfea9ea65ebb7974e6242d310d2a7772a6f015477e0d79993af4511"}, | ||||
|     {file = "protobuf-4.21.8-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:b02eabb9ebb1a089ed20626a90ad7a69cee6bcd62c227692466054b19c38dd1f"}, | ||||
|     {file = "protobuf-4.21.8-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:4761201b93e024bb70ee3a6a6425d61f3152ca851f403ba946fb0cde88872661"}, | ||||
|     {file = "protobuf-4.21.8-cp37-cp37m-win32.whl", hash = "sha256:f2d55ff22ec300c4d954d3b0d1eeb185681ec8ad4fbecff8a5aee6a1cdd345ba"}, | ||||
|     {file = "protobuf-4.21.8-cp37-cp37m-win_amd64.whl", hash = "sha256:c5f94911dd8feb3cd3786fc90f7565c9aba7ce45d0f254afd625b9628f578c3f"}, | ||||
|     {file = "protobuf-4.21.8-cp38-cp38-win32.whl", hash = "sha256:b37b76efe84d539f16cba55ee0036a11ad91300333abd213849cbbbb284b878e"}, | ||||
|     {file = "protobuf-4.21.8-cp38-cp38-win_amd64.whl", hash = "sha256:2c92a7bfcf4ae76a8ac72e545e99a7407e96ffe52934d690eb29a8809ee44d7b"}, | ||||
|     {file = "protobuf-4.21.8-cp39-cp39-win32.whl", hash = "sha256:89d641be4b5061823fa0e463c50a2607a97833e9f8cfb36c2f91ef5ccfcc3861"}, | ||||
|     {file = "protobuf-4.21.8-cp39-cp39-win_amd64.whl", hash = "sha256:bc471cf70a0f53892fdd62f8cd4215f0af8b3f132eeee002c34302dff9edd9b6"}, | ||||
|     {file = "protobuf-4.21.8-py2.py3-none-any.whl", hash = "sha256:a55545ce9eec4030cf100fcb93e861c622d927ef94070c1a3c01922902464278"}, | ||||
|     {file = "protobuf-4.21.8-py3-none-any.whl", hash = "sha256:0f236ce5016becd989bf39bd20761593e6d8298eccd2d878eda33012645dc369"}, | ||||
|     {file = "protobuf-4.21.8.tar.gz", hash = "sha256:427426593b55ff106c84e4a88cac855175330cb6eb7e889e85aaa7b5652b686d"}, | ||||
| ] | ||||
| protobuf3 = [ | ||||
|     {file = "protobuf3-0.2.1.tar.gz", hash = "sha256:ddd878b3f991beff566ab384d3588cf8e89758e3a16a78f4099dbe70de3c41a2"}, | ||||
| ] | ||||
| py = [ | ||||
|     {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, | ||||
|     {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, | ||||
| ] | ||||
| pylint = [ | ||||
|     {file = "pylint-2.15.4-py3-none-any.whl", hash = "sha256:629cf1dbdfb6609d7e7a45815a8bb59300e34aa35783b5ac563acaca2c4022e9"}, | ||||
|     {file = "pylint-2.15.4.tar.gz", hash = "sha256:5441e9294335d354b7bad57c1044e5bd7cce25c433475d76b440e53452fa5cb8"}, | ||||
| ] | ||||
| pyparsing = [ | ||||
|     {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, | ||||
|     {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, | ||||
| ] | ||||
| pytest = [ | ||||
|     {file = "pytest-7.1.3-py3-none-any.whl", hash = "sha256:1377bda3466d70b55e3f5cecfa55bb7cfcf219c7964629b967c37cf0bda818b7"}, | ||||
|     {file = "pytest-7.1.3.tar.gz", hash = "sha256:4f365fec2dff9c1162f834d9f18af1ba13062db0c708bf7b946f8a5c76180c39"}, | ||||
| ] | ||||
| pytest-mock = [ | ||||
|     {file = "pytest-mock-3.10.0.tar.gz", hash = "sha256:fbbdb085ef7c252a326fd8cdcac0aa3b1333d8811f131bdcc701002e1be7ed4f"}, | ||||
|     {file = "pytest_mock-3.10.0-py3-none-any.whl", hash = "sha256:f4c973eeae0282963eb293eb173ce91b091a79c1334455acfac9ddee8a1c784b"}, | ||||
| ] | ||||
| python-dateutil = [ | ||||
|     {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, | ||||
|     {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, | ||||
| ] | ||||
| pyyaml = [ | ||||
|     {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, | ||||
|     {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, | ||||
|     {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, | ||||
|     {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, | ||||
|     {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, | ||||
|     {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, | ||||
|     {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, | ||||
|     {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, | ||||
|     {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, | ||||
|     {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, | ||||
|     {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, | ||||
|     {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, | ||||
|     {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, | ||||
|     {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, | ||||
|     {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, | ||||
|     {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, | ||||
|     {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, | ||||
|     {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, | ||||
|     {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, | ||||
|     {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, | ||||
|     {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, | ||||
|     {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, | ||||
|     {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, | ||||
|     {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, | ||||
|     {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, | ||||
|     {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, | ||||
|     {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, | ||||
|     {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, | ||||
|     {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, | ||||
|     {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, | ||||
|     {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, | ||||
|     {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, | ||||
|     {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, | ||||
|     {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, | ||||
|     {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, | ||||
|     {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, | ||||
|     {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, | ||||
|     {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, | ||||
|     {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, | ||||
|     {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, | ||||
| ] | ||||
| requests = [ | ||||
|     {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, | ||||
|     {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, | ||||
| ] | ||||
| s3transfer = [ | ||||
|     {file = "s3transfer-0.6.0-py3-none-any.whl", hash = "sha256:06176b74f3a15f61f1b4f25a1fc29a4429040b7647133a463da8fa5bd28d5ecd"}, | ||||
|     {file = "s3transfer-0.6.0.tar.gz", hash = "sha256:2ed07d3866f523cc561bf4a00fc5535827981b117dd7876f036b0c1aca42c947"}, | ||||
| ] | ||||
| six = [ | ||||
|     {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, | ||||
|     {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, | ||||
| ] | ||||
| soupsieve = [ | ||||
|     {file = "soupsieve-2.3.2.post1-py3-none-any.whl", hash = "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759"}, | ||||
|     {file = "soupsieve-2.3.2.post1.tar.gz", hash = "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d"}, | ||||
| ] | ||||
| tomli = [ | ||||
|     {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, | ||||
|     {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, | ||||
| ] | ||||
| tomlkit = [ | ||||
|     {file = "tomlkit-0.11.5-py3-none-any.whl", hash = "sha256:f2ef9da9cef846ee027947dc99a45d6b68a63b0ebc21944649505bf2e8bc5fe7"}, | ||||
|     {file = "tomlkit-0.11.5.tar.gz", hash = "sha256:571854ebbb5eac89abcb4a2e47d7ea27b89bf29e09c35395da6f03dd4ae23d1c"}, | ||||
| ] | ||||
| urllib3 = [ | ||||
|     {file = "urllib3-1.26.12-py2.py3-none-any.whl", hash = "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997"}, | ||||
|     {file = "urllib3-1.26.12.tar.gz", hash = "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e"}, | ||||
| ] | ||||
| wrapt = [ | ||||
|     {file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"}, | ||||
|     {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef"}, | ||||
|     {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28"}, | ||||
|     {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59"}, | ||||
|     {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87"}, | ||||
|     {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1"}, | ||||
|     {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b"}, | ||||
|     {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462"}, | ||||
|     {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1"}, | ||||
|     {file = "wrapt-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320"}, | ||||
|     {file = "wrapt-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2"}, | ||||
|     {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4"}, | ||||
|     {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069"}, | ||||
|     {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310"}, | ||||
|     {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f"}, | ||||
|     {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656"}, | ||||
|     {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c"}, | ||||
|     {file = "wrapt-1.14.1-cp310-cp310-win32.whl", hash = "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8"}, | ||||
|     {file = "wrapt-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164"}, | ||||
|     {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907"}, | ||||
|     {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3"}, | ||||
|     {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3"}, | ||||
|     {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d"}, | ||||
|     {file = "wrapt-1.14.1-cp35-cp35m-win32.whl", hash = "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7"}, | ||||
|     {file = "wrapt-1.14.1-cp35-cp35m-win_amd64.whl", hash = "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00"}, | ||||
|     {file = "wrapt-1.14.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4"}, | ||||
|     {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1"}, | ||||
|     {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1"}, | ||||
|     {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff"}, | ||||
|     {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d"}, | ||||
|     {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1"}, | ||||
|     {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569"}, | ||||
|     {file = "wrapt-1.14.1-cp36-cp36m-win32.whl", hash = "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed"}, | ||||
|     {file = "wrapt-1.14.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471"}, | ||||
|     {file = "wrapt-1.14.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248"}, | ||||
|     {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68"}, | ||||
|     {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d"}, | ||||
|     {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77"}, | ||||
|     {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7"}, | ||||
|     {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015"}, | ||||
|     {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a"}, | ||||
|     {file = "wrapt-1.14.1-cp37-cp37m-win32.whl", hash = "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853"}, | ||||
|     {file = "wrapt-1.14.1-cp37-cp37m-win_amd64.whl", hash = "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c"}, | ||||
|     {file = "wrapt-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456"}, | ||||
|     {file = "wrapt-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f"}, | ||||
|     {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc"}, | ||||
|     {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1"}, | ||||
|     {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af"}, | ||||
|     {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b"}, | ||||
|     {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0"}, | ||||
|     {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57"}, | ||||
|     {file = "wrapt-1.14.1-cp38-cp38-win32.whl", hash = "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5"}, | ||||
|     {file = "wrapt-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d"}, | ||||
|     {file = "wrapt-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383"}, | ||||
|     {file = "wrapt-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7"}, | ||||
|     {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86"}, | ||||
|     {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735"}, | ||||
|     {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b"}, | ||||
|     {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3"}, | ||||
|     {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3"}, | ||||
|     {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe"}, | ||||
|     {file = "wrapt-1.14.1-cp39-cp39-win32.whl", hash = "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5"}, | ||||
|     {file = "wrapt-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb"}, | ||||
|     {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, | ||||
| ] | ||||
							
								
								
									
										43
									
								
								pyproject.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								pyproject.toml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| [tool.poetry] | ||||
| name = "robocar-oak-camera" | ||||
| version = "0.0.0" | ||||
| description = "Mqtt gateway for oak-lite device" | ||||
| authors = ["Cyrille Nofficial <cynoffic@cyrilix.fr>"] | ||||
| readme = "README.md" | ||||
| packages = [ | ||||
|     { include = "camera" }, | ||||
|     { include = "events" }, | ||||
| ] | ||||
|  | ||||
| [tool.poetry.dependencies] | ||||
| python = "^3.10" | ||||
| paho-mqtt = "^1.6.1" | ||||
| depthai = "^2.17.4.0" | ||||
| protobuf3 = "^0.2.1" | ||||
| google = "^3.0.0" | ||||
| opencv-python = "^4.6.0.66" | ||||
| blobconverter = "^1.3.0" | ||||
| protobuf = "^4.21.8" | ||||
|  | ||||
|  | ||||
| [tool.poetry.group.test.dependencies] | ||||
| pytest = "^7.1.3" | ||||
| pytest-mock = "^3.10.0" | ||||
|  | ||||
|  | ||||
| [tool.poetry.group.dev.dependencies] | ||||
| pylint = "^2.15.4" | ||||
|  | ||||
| [build-system] | ||||
| requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning"] | ||||
| build-backend = "poetry_dynamic_versioning.backend" | ||||
|  | ||||
| [tool.poetry.scripts] | ||||
| rc-oak-camera = 'camera.cli:execute_from_command_line' | ||||
|  | ||||
| [tool.poetry-dynamic-versioning] | ||||
| enable = true | ||||
| style = 'semver' | ||||
| vcs = 'git' | ||||
| dirty = true | ||||
| bump = true | ||||
| @@ -1,8 +0,0 @@ | ||||
| paho-mqtt~=1.6.1 | ||||
| docopt~=0.6.2 | ||||
| depthai==2.17.2.0 | ||||
| opencv-python==4.6.0.66 | ||||
| google~=3.0.0 | ||||
| google-api-core~=2.4.0 | ||||
| setuptools==60.5.0 | ||||
| blobconverter==1.3.0 | ||||
| @@ -1,5 +0,0 @@ | ||||
| [metadata] | ||||
| description-file = README.md | ||||
|  | ||||
| [aliases] | ||||
| test = pytest | ||||
							
								
								
									
										68
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								setup.py
									
									
									
									
									
								
							| @@ -1,68 +0,0 @@ | ||||
| import os | ||||
|  | ||||
| from setuptools import setup, find_packages | ||||
|  | ||||
|  | ||||
| # include the non python files | ||||
| def package_files(directory, strip_leading): | ||||
|     paths = [] | ||||
|     for (path, directories, filenames) in os.walk(directory): | ||||
|         for filename in filenames: | ||||
|             package_file = os.path.join(path, filename) | ||||
|             paths.append(package_file[len(strip_leading):]) | ||||
|     return paths | ||||
|  | ||||
|  | ||||
| tests_require = ['pytest', | ||||
|                  ] | ||||
|  | ||||
| setup(name='robocar-oak-camera', | ||||
|       version='0.1', | ||||
|       description='Mqtt gateway for oak-lite device.', | ||||
|       url='https://github.com/cyrilix/robocar-oak-camera', | ||||
|       license='Apache2', | ||||
|       entry_points={ | ||||
|           'console_scripts': [ | ||||
|               'rc-oak-camera=camera.cli:execute_from_command_line', | ||||
|           ], | ||||
|       }, | ||||
|       setup_requires=['pytest-runner'], | ||||
|       install_requires=['depthai', | ||||
|                         'docopt', | ||||
|                         'paho-mqtt', | ||||
|                         'protobuf3', | ||||
|                         'google', | ||||
|                         'numpy', | ||||
|                         'opencv-python', | ||||
|                         'blobconverter', | ||||
|                         ], | ||||
|       tests_require=tests_require, | ||||
|       extras_require={ | ||||
|           'tests': tests_require | ||||
|       }, | ||||
|  | ||||
|       include_package_data=True, | ||||
|  | ||||
|       classifiers=[ | ||||
|           # How mature is this project? Common values are | ||||
|           #   3 - Alpha | ||||
|           #   4 - Beta | ||||
|           #   5 - Production/Stable | ||||
|           'Development Status :: 3 - Alpha', | ||||
|  | ||||
|           # Indicate who your project is intended for | ||||
|           'Intended Audience :: Developers', | ||||
|           'Topic :: Scientific/Engineering :: Artificial Intelligence', | ||||
|  | ||||
|           # Pick your license as you wish (should match "license" above) | ||||
|           'License :: OSI Approved :: Apache 2 License', | ||||
|  | ||||
|           # Specify the Python versions you support here. In particular, ensure | ||||
|           # that you indicate whether you support Python 2, Python 3 or both. | ||||
|  | ||||
|           'Programming Language :: Python :: 3.7', | ||||
|       ], | ||||
|       keywords='selfdriving cars drive', | ||||
|  | ||||
|       packages=find_packages(exclude=(['tests', 'env'])), | ||||
|       ) | ||||
		Reference in New Issue
	
	Block a user